【问题标题】:XML Processing in PythonPython 中的 XML 处理
【发布时间】:2010-09-05 05:55:27
【问题描述】:

我将要构建一个项目的一部分,该项目需要构建 XML 文档并将其发布到 Web 服务,我想用 Python 来完成它,以扩展我的技能。

不幸的是,虽然我非常了解 .NET 中的 XML 模型,但我不确定 Python 中的 XML 模型的优缺点是什么。

任何人都有在 Python 中进行 XML 处理的经验吗?你建议我从哪里开始?我将要构建的 XML 文件将相当简单。

【问题讨论】:

标签: python xml


【解决方案1】:

我假设 .NET 处理 XML 的方式是建立在某个版本的 MSXML 之上的,在这种情况下,我假设使用 minidom 等工具会让您有宾至如归的感觉。但是,如果您正在进行简单的处理,任何库都可能会这样做。

在 Python 中处理 XML 时,我也更喜欢使用 ElementTree,因为它是一个非常简洁的库。

【讨论】:

    【解决方案2】:

    我编写了一个接收 XML 请求并创建 XML 响应的 SOAP 服务器。 (很遗憾,这不是我的项目,所以它是闭源的,但这是另一个问题)。

    对我来说,如果您有一个“适合”架构的数据结构,那么创建 (SOAP) XML 文档是相当简单的。

    我保留信封,因为响应信封(几乎)与请求信封相同。然后,由于我的数据结构是一个(可能是嵌套的)字典,我创建了一个字符串,将该字典转换为 value 项。

    这是一个递归简化的任务,我最终得到了正确的结构。这一切都是在 python 代码中完成的,目前对于生产使用来说已经足够快了。

    您也可以(相对)轻松地构建列表,尽管取决于您的客户,除非您给出长度提示,否则您可能会遇到问题。

    对我来说,这要简​​单得多,因为字典比某些自定义类更容易工作。对于书来说,生成 XML 比解析容易多了!

    【讨论】:

      【解决方案3】:

      要在 Python 中认真处理 XML,请使用 lxml

      Python 带有 ElementTree 内置库,但 lxml 在速度和功能(模式验证、sax 解析、XPath、各种迭代器和许多其他功能)方面对其进行了扩展。

      您必须安装它,但在许多地方,它已经被假定为标准设备的一部分(例如 Google AppEngine 不允许基于 C 的 Python 包,但对 lxml、pyyaml 和其他少数几个例外) .

      使用 E-factory 构建 XML 文档(来自 lxml)

      您的问题是关于构建 XML 文档的。

      lxml的方法很多,找了好久才找到,貌似好用也好读。

      来自lxml doc on using E-factory 的示例代码(略微简化):


      E-factory 为生成 XML 和 HTML 提供了一种简单而紧凑的语法:

      >>> from lxml.builder import E
      
      >>> html = page = (
      ...   E.html(       # create an Element called "html"
      ...     E.head(
      ...       E.title("This is a sample document")
      ...     ),
      ...     E.body(
      ...       E.h1("Hello!"),
      ...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
      ...       E.p("This is another paragraph, with a", "\n      ",
      ...         E.a("link", href="http://www.python.org"), "."),
      ...       E.p("Here are some reserved characters: <spam&egg>."),
      ...     )
      ...   )
      ... )
      
      >>> print(etree.tostring(page, pretty_print=True))
      <html>
        <head>
          <title>This is a sample document</title>
        </head>
        <body>
          <h1>Hello!</h1>
          <p>This is a paragraph with <b>bold</b> text in it!</p>
          <p>This is another paragraph, with a
            <a href="http://www.python.org">link</a>.</p>
          <p>Here are some reserved characters: &lt;spam&amp;egg&gt;.</p>
        </body>
      </html>
      

      我很欣赏 E-factory 它遵循的东西

      代码读取几乎与生成的 XML 文档一样

      可读性很重要。

      允许创建任何 XML 内容

      支持以下内容:

      • 命名空间的使用
      • 一个元素内的开始和结束文本节点
      • 函数格式化属性内容(参见full lxml sample中的func CLASS)

      允许非常易读的列表结构

      例如:

      from lxml import etree
      from lxml.builder import E
      lst = ["alfa", "beta", "gama"]
      xml = E.root(*[E.record(itm) for itm in lst])
      etree.tostring(xml, pretty_print=True)
      

      导致:

      <root>
        <record>alfa</record>
        <record>beta</record>
        <record>gama</record>
      </root>
      

      结论

      我强烈推荐阅读 lxml 教程——它写得非常好,会给你更多使用这个强大库的理由。

      lxml 唯一的缺点是它必须被编译。请参阅SO answer for more tips 如何在几分之一秒内从 wheel 格式包中安装 lxml。

      【讨论】:

        【解决方案4】:

        我强烈推荐SAX - Simple API for XML - 在 Python 库中实现。它们相当容易设置和处理大型XML,甚至驱动API,正如之前的海报所讨论的那样,并且与验证DOM 样式XML 解析器不同,它们具有较低的内存占用。

        【讨论】:

          【解决方案5】:

          您也可以尝试untangle 来解析简单的 XML 文档。

          【讨论】:

            【解决方案6】:

            这在一定程度上取决于文档需要有多复杂。

            我在编写 XML 时经常使用 minidom,但通常只是读取文档,进行一些简单的转换,然后将它们写回。直到我需要对元素属性进行排序的能力(以满足不能正确解析 XML 的古老应用程序)之前,这已经足够好用了。那时我放弃了,自己编写了 XML。

            如果您只处理简单的文档,那么自己动手会比学习框架更快、更简单。如果您可以想象手动编写 XML,那么您也可以手动编写它(只要记住正确转义特殊字符,并使用 str.encode(codec, errors="xmlcharrefreplace"))。除了这些混乱之外,XML 足够规则,您不需要一个特殊的库来编写它。如果文档太复杂而无法手动编写,那么您可能应该查看已经提到的框架之一。任何时候都不需要编写通用的 XML 编写器。

            【讨论】:

              【解决方案7】:

              如果您要构建 SOAP 消息,请查看 soaplib。它在底层使用 ElementTree,但它为序列化和反序列化消息提供了更简洁的接口。

              【讨论】:

                【解决方案8】:

                我在几个项目中使用过 ElementTree 并推荐它。

                它是 Python 的,随 Python 2.5 提供,包括 c 版本的 cElementTree (xml.etree.cElementTree),它比纯 Python 版本快 20 倍,并且非常易于使用。

                lxml 具有一些性能优势,但它们并不均衡,您应该首先检查您的用例的基准。

                据我了解,ElementTree 代码可以轻松移植到 lxml。

                【讨论】:

                  【解决方案9】:

                  通常有 3 种主要的处理 XML 的方法:dom、sax 和 xpath。如果您有能力一次将整个 xml 文件加载到内存中,并且您不介意处理数据结构,并且您正在查看大部分/大部分模型,则 dom 模型很好。如果您只关心几个标签,并且/或者您正在处理大文件并且可以按顺序处理它们,那么 sax 模型非常棒。 xpath 模型各有不同——您可以选择所需数据元素的路径,但它需要使用更多库。

                  如果你想直接使用 Python 打包,minidom 是你的答案,但它很蹩脚,文档是“这里是 dom 上的文档,去弄清楚”。真的很烦。

                  就我个人而言,我喜欢 cElementTree,它是 ElementTree 的一个更快(基于 c 的)实现,它是一个类似 dom 的模型。

                  我使用过 sax 系统,并且在很多方面它们的感觉更像是“pythonic”,但我通常最终会创建基于状态的系统来处理它们,而这就是疯狂(和错误)。

                  如果你喜欢研究,我说使用 minidom,如果你想要运行良好的好代码,我说使用 ElementTree。

                  【讨论】:

                  • 在Python中,还有其他方式,比如ElementTree(见Gareth Simpson的回复)
                  【解决方案10】:

                  由于您提到您将构建“相当简单”的 XML,minidom module(Python 标准库的一部分)可能会满足您的需求。如果您对 XML 的 DOM 表示有任何经验,您应该会发现 API 非常简单。

                  【讨论】:

                    【解决方案11】:

                    ElementTree 有一个不错的 pythony API。我认为它甚至是作为 python 2.5 的一部分发布的

                    它是在纯 python 中,正如我所说,非常好,但如果你最终需要更高的性能,那么lxml 会公开相同的 API 并在后台使用 libxml2。理论上,您可以在发现需要时将其换掉。

                    【讨论】:

                    • 为了完成你的答案,你能补充一下 lxml 还支持 XML 模式和 XPath,ElementTree 不支持吗?它确实随 Python 2.5 一起提供。
                    • ElementTree 在你需要处理命名空间之前很好,然后它就会崩溃并且无法使用。
                    【解决方案12】:

                    就个人而言,我在一个 XML 繁重的项目中使用了几个内置选项,并确定 pulldom 作为不太复杂的文档的最佳选择。

                    特别是对于简单的小东西,我喜欢事件驱动的解析理论,而不是为一个相对简单的结构设置一整套回调。 Here is a good quick discussion of how to use the API.

                    我喜欢的是:您可以在 for 循环中处理解析,而不是使用回调。您还延迟了完整解析(“拉”部分),并且只有在您调用 expandNode() 时才能获得更多详细信息。这在不牺牲易用性和简单性的情况下满足了我对“负责任”效率的一般要求。

                    【讨论】:

                    • 难道 pulldom 不是解析 XML 的工具,而不是生成它(这是问题要问的)?
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-07-08
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-04-19
                    • 1970-01-01
                    • 2013-08-20
                    相关资源
                    最近更新 更多