【问题标题】:ElementTree in Python 2.6.2 Processing Instructions support?Python 2.6.2 处理指令中的 ElementTree 支持?
【发布时间】:2009-09-29 00:09:27
【问题描述】:

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

【问题讨论】:

    标签: python xml elementtree


    【解决方案1】:

    试试lxml 库:它遵循 ElementTree api,并添加了许多附加功能。来自compatibility overview

    ElementTree 在解析 XML 时会忽略 cmets 和处理指令,而 etree 会将它们读入并分别将它们视为 Comment 或 ProcessingInstruction 元素。这在文本内容中发现 cmets 时尤其明显,然后由 Comment 元素分割。

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

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

    【讨论】:

      【解决方案2】:

      使用 lxml API 再简单不过了,尽管它有点“文档不足”:

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

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

      生成的文档将如下所示:

      <?anypi anypicontent?>
      <anytagname />
      

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

      【讨论】:

      • 这不在根元素上。
      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

        我对 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>
        

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

        祝你的项目好运。

        【讨论】:

          【解决方案5】:
          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:])
          

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-08-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-22
            • 2012-07-08
            • 1970-01-01
            • 2011-11-06
            相关资源
            最近更新 更多