Python 2.6.2中的ElementTree处理指令支持?

时间:2009-09-29 00:09:28

标签: python xml elementtree

我正在尝试使用python中的ElementTree对象结构创建XML。除了处理指令外,一切都很好。我可以使用工厂函数ProcessingInstruction()轻松创建PI,但不会将其添加到elementtree中。我可以手动添加它,但我无法弄清楚如何将它添加到通常放置PI的根元素之上。有人知道怎么做吗?我知道有很多替代方法可以做到这一点,但似乎必须建立在我无法找到的地方。

5 个答案:

答案 0 :(得分:6)

使用lxml API它可能不容易,虽然它有点“未记录”:

如果您需要顶级处理指令,请按以下方式创建:

from lxml import etree

root = etree.Element("anytagname")
root.addprevious(etree.ProcessingInstruction("anypi", "anypicontent"))

结果文档如下所示:

<?anypi anypicontent?>
<anytagname />

他们当然应该将这个添加到他们的常见问题解答中,因为IMO是另一个将这个优秀API分开的功能。

答案 1 :(得分:5)

尝试使用lxml库:它遵循ElementTree api,并添加了许多额外内容。来自compatibility overview

  

Elementtree在解析XML时忽略注释和处理指令,而etree将读取它们并分别将它们视为Comment或ProcessingInstruction元素。这在文本内容中找到注释时尤其明显,然后由Comment元素分割。

     

您可以通过将布尔remove_comments和/或remove_pis关键字参数传递给您使用的解析器来禁用此行为。为方便起见并支持可移植代码,您还可以使用etree.ETCompatXMLParser代替默认etree.XMLParser。它尝试提供尽可能接近ElementTree解析器的默认设置。

我知道,不是在stdlib中,但根据我的经验,当您需要标准ElementTree不提供的内容时,最好的选择。

答案 2 :(得分:2)

是的,我不相信这是可能的,对不起。 ElementTree为(非命名空间的)以元素为中心的XML处理提供了比DOM更简单的接口,但其代价是它不支持整个XML信息集。

没有明显的方法来表示位于根元素之外的内容(注释,PI,doctype和XML声明),并且这些内容也会在分析时被丢弃。 (旁白:这似乎包括DTD内部子集中指定的任何默认属性,这使得ElementTree严格地说是不兼容的XML处理器。)

你可以通过子类化或猴子修补Python本机ElementTree实现的write()方法在你的额外PI上调用_write来编写_root之前解决它,但它可能是有点脆弱。

如果您需要支持完整的XML信息集,可能最好坚持使用DOM。

答案 3 :(得分:1)

我对ElementTree了解不多。但是你有可能使用我写的名为“xe”的库来解决你的问题。

xe是一组Python类,旨在使创建结构化XML变得容易。由于各种原因,我很长时间没有参与其中,但如果您对此有疑问或需要修复错误,我愿意帮助您。

它对处理指令之类的东西提供了支持,而且我认为它可以做你需要的一些工作。 (当我开始添加处理指令时,我并不真正理解它们,我对它们没有任何需求,因此代码有点半生不熟。)

看看它是否有用。

http://home.avvanta.com/~steveha/xe.html

以下是使用它的示例:

import xe
doc = xe.XMLDoc()

prefs = xe.NestElement("prefs")
prefs.user_name = xe.TextElement("user_name")
prefs.paper = xe.NestElement("paper")
prefs.paper.width = xe.IntElement("width")
prefs.paper.height = xe.IntElement("height")

doc.root_element = prefs


prefs.user_name = "John Doe"
prefs.paper.width = 8
prefs.paper.height = 10

c = xe.Comment("this is a comment")
doc.top.append(c)

如果您运行上面的代码然后运行print doc,那么您将获得:

<?xml version="1.0" encoding="utf-8"?>
<!-- this is a comment -->
<prefs>
    <user_name>John Doe</user_name>
    <paper>
        <width>8</width>
        <height>10</height>
    </paper>
</prefs>

如果您对此感兴趣但需要一些帮助,请告诉我。

祝你的项目好运。

答案 4 :(得分:0)

f = open('D:\Python\XML\test.xml', 'r+')
old = f.read()
f.seek(44,0)      #place cursor after xml declaration
f.write('<?xml-stylesheet type="text/xsl" href="C:\Stylesheets\expand.xsl"?>'+ old[44:])

即使在我的案例root.insert (0, PI)中使用了一个Element方法并尝试多种切割方法之后,我也未能正确地将PI插入到.xml文件中,我遇到了同样的问题并提出了这个粗略的解决方案并将插入的PI粘贴到正确的位置,以查找要从意外位置删除的数据。