82

我即将构建一个需要构建 XML 文档并将其发布到 Web 服务的项目的一部分,并且我想用 Python 来完成它,作为扩展我在其中的技能的一种手段。

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

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

4

12 回答 12

35

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

特别是对于简单的小东西,我喜欢事件驱动的解析理论,而不是为一个相对简单的结构设置一大堆回调。 这是关于如何使用 API 的一个很好的快速讨论

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

于 2008-08-02T04:01:34.600 回答
33

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

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

于 2008-08-02T15:21:03.587 回答
8

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

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

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

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

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

于 2008-09-16T04:35:28.113 回答
8

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

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

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

据我了解,ElementTree 代码可以很容易地移植到 lxml。

于 2008-09-23T19:42:58.003 回答
8

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

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

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

于 2008-10-14T18:26:04.833 回答
7

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

于 2011-10-31T14:05:09.450 回答
6

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

于 2008-08-02T18:04:10.543 回答
6

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

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

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

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

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

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

于 2008-08-03T08:34:57.103 回答
5

在 Python 中认真使用 XML 时,请使用 lxml

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

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

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

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

使用lxml有很多方法,我花了一段时间才找到一个,它似乎易于使用且易于阅读。

来自lxml doc 中关于使用 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 内容

支持以下内容:

  • 命名空间的使用
  • 一个元素内的开始和结束文本节点
  • 格式化属性内容的函数(参见完整 lxml 示例中的 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 唯一的缺点是它必须被编译。有关如何在几分之一秒内从 wheel 格式包安装 lxml的更多提示,请参阅SO answer。

于 2014-04-17T21:32:13.397 回答
3

我强烈推荐SAX - Simple API for XML- 在 Python 库中实现。正如之前的海报所讨论的,它们相当容易通过 evendriven 设置和处理XMLAPI并且与验证DOM样式XML解析器不同,内存占用量低。

于 2012-12-12T03:25:50.733 回答
2

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

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

于 2008-09-16T06:20:01.683 回答
2

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

于 2008-10-13T22:17:10.467 回答