Python 2.6.2中的ElementTree对处理指令的支持?
我正在尝试使用Python中的ElementTree对象结构来创建XML。整体上运行得很好,但在处理指令时遇到了一些问题。我可以很容易地使用ProcessingInstruction()这个工厂函数来创建一个处理指令,但它并没有被添加到元素树中。我可以手动添加,但我不知道怎么把它放在根元素上面,因为处理指令通常是放在那里的。有没有人知道怎么做到这一点?我知道有很多其他的方法可以实现这个,但似乎这个功能应该是内置的,只是我找不到。
5 个回答
嗯,我觉得这可能不行,抱歉。ElementTree 提供了一种比 DOM 更简单的方式来处理没有命名空间的 XML,但代价就是它不支持完整的 XML 信息集。
在根元素外的内容(比如注释、处理指令、文档类型和 XML 声明)没有明显的方法可以表示,而且这些内容在解析时也会被丢弃。(顺便说一下,这似乎还包括 DTD 内部子集里指定的任何默认属性,这使得 ElementTree 严格来说并不是一个合规的 XML 处理器。)
你可能可以通过子类化或者修改 Python 原生 ElementTree 实现的 write()
方法,来在写入 _root
之前先调用 _write
来处理你的额外的处理指令,但这样做可能会有点脆弱。
如果你需要支持完整的 XML 信息集,最好还是使用 DOM。
使用lxml这个工具,创建处理指令非常简单,不过它的说明文档有点少。
如果你需要一个顶层的处理指令,可以这样创建:
from lxml import etree
root = etree.Element("anytagname")
root.addprevious(etree.ProcessingInstruction("anypi", "anypicontent"))
生成的文档会是这个样子的:
<?anypi anypicontent?>
<anytagname />
我觉得他们应该把这个加到常见问题里,因为这确实是让这个工具与众不同的一个功能。
试试 lxml
这个库吧:它遵循 ElementTree 的接口,还增加了很多额外的功能。从 兼容性概述来看:
ElementTree 在解析 XML 时会忽略注释和处理指令,而 etree 会把它们读进来,并分别当作注释或处理指令元素。这一点在文本内容中有注释时特别明显,因为这些注释会把文本内容分开。
你可以通过给解析器传递布尔值
remove_comments
和/或remove_pis
这两个参数来关闭这种行为。为了方便和支持可移植的代码,你也可以使用etree.ETCompatXMLParser
,而不是默认的etree.XMLParser
。它会尽量提供一个与 ElementTree 解析器尽可能接近的默认设置。
我知道它不在标准库里,但根据我的经验,当你需要标准 ElementTree 不提供的功能时,这是最好的选择。