如何使用lxml.objectify创建带文本内容的对象化XML元素
使用lxml.objectify创建带文本节点的XML元素树
目标需求
需要从零创建(而非解析现有XML文件/字符串)如下结构的XML:
<root> <child>Hello World</child> </root>
踩坑表现
最初的实现代码把文本作为text关键字参数传入元素构造方法:
import lxml.objectify as o from lxml.etree import tounicode r = o.Element("root") c = o.Element("child", text="Hello World") r.append(c) print(tounicode(r, pretty_print=True))
运行后输出不符合预期:会自动带上一堆objectify的类型命名空间,Hello World没有成为子节点的文本,反而变成了text属性,子节点变成了自闭合标签:
<root xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" py:pytype="TREE"> <child text="Hello World" data="Test" py:pytype="TREE"/> </root>
之前查到的_setText方法是lxml非常早期版本的私有接口,当前版本已经移除,直接调用会报属性不存在的错误。
正确实现方案
lxml.objectify的设计逻辑和原生lxml.etree不同,不需要手动给text属性赋值,也不需要调用特殊私有方法,直接按照对象属性赋值的方式操作即可:
import lxml.objectify as o from lxml.etree import tounicode # 创建根节点 root = o.Element("root") # 直接给根节点的child属性赋值字符串,objectify会自动创建<child>子节点,并将字符串作为节点文本 root.child = "Hello World" # 输出时传入pytype=False,即可去掉自动添加的类型相关命名空间,得到干净的XML print(tounicode(root, pretty_print=True, pytype=False))
运行后输出完全匹配目标结构:
<root> <child>Hello World</child> </root>
补充说明
- 不要在
o.Element()构造方法里传text参数,这种传法会被识别为给元素添加XML属性,而非设置文本节点 - 修改已有元素的文本也可以直接赋值,比如后续执行
root.child = "新的文本内容"就可以直接更新子节点的文本,不需要操作底层属性 - 如果需要创建多个同名子节点,可以使用
o.SubElement方法创建后,直接给新创建的子元素对象赋值字符串即可
内容的提问来源于stack exchange,提问作者Andi
相关产品推荐
相关产品推荐

