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

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

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

有帮助吗?

解决方案

就我个人而言,我在一个 XML 密集型项目中尝试过几个内置选项,并决定使用 普鲁多姆 作为不太复杂的文档的最佳选择。

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

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

其他提示

元素树 有一个很好的 pythony API。我认为它甚至作为 python 2.5 的一部分提供

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

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

如果你想要简单并用 Python 打包,minidom 就是你的答案,但它非常蹩脚,并且文档是“这里有 dom 上的文档,去弄清楚”。真的很烦人。

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

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

我说如果你喜欢研究,就选择 minidom;如果你想要运行良好的代码,就选择 ElementTree。

我已经将 ElementTree 用于多个项目并推荐它。

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

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

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

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

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

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

你也可以尝试 解开 解析简单的 XML 文档。

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

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

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

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

这是一个递归使任务变得简单的任务,我最终得到了正确的结构。这一切都是用 python 代码完成的,目前速度足以满足生产使用。

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

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

对于在 Python 中认真使用 XML 的工作,请使用 lxml

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

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

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

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

lxml 有很多方法,我花了一段时间才找到一个,看起来很容易使用,也很容易阅读。

示例代码来自 关于使用 E-factory 的 lxml 文档 (稍微简化):


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 内容

支持以下内容:

  • 命名空间的使用
  • 一个元素内的起始和结束文本节点
  • 函数格式化属性内容(请参阅 func CLASS 中 完整的 lxml 示例)

允许使用列表构建非常可读的结构

例如。:

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。

如果您要构建 SOAP 消息,请查看 肥皂库. 。它在底层使用 ElementTree,但它提供了一个更清晰的接口来序列化和反序列化消息。

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top