Python 中的 XML 处理

Posted

技术标签:

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

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

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

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

【问题讨论】:

Dive Into Python 有一个章节。但不能保证它会有多好。 第一个python问题 【参考方案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 的工具,而不是生成它(这是问题要问的)?

以上是关于Python 中的 XML 处理的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 转义 XML 中的未转义字符

python使用SAX解析xml

python的XML处理模块ElementTree

Python之在字符串中处理html和xml

python按层级找出xml文件的差异

Spark 中的 XML 处理