Python中的XML处理

saa*_*lon 68 python xml

我即将构建一个需要构建XML文档并将其发布到Web服务的项目,我希望用Python来实现,作为扩展我的技能的一种方法.

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

有没有经验在Python中进行XML处理?你会建议我从哪里开始?我将构建的XML文件非常简单.

Gar*_*son 31

ElementTree有一个很好的pythony API.我认为它甚至作为python 2.5的一部分发布

它是纯粹的python,正如我所说,非常好,但如果你最终需要更多的性能,那么lxml暴露相同的API并使用libxml2.理论上,当您发现需要它时,您可以将其交换.

  • ElementTree是好的,直到你需要处理命名空间然后它崩溃,它是无法使用的. (2认同)

sai*_*eon 28

就个人而言,我已经在XML重型项目中使用了几个内置选项,并且已经将pulldom作为不太复杂文档的最佳选择.

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

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


Mat*_*att 6

既然你提到你将构建"相当简单"的XML,那么minidom模块(Python标准库的一部分)可能会满足你的需求.如果您对XML的DOM表示有任何经验,那么您应该非常直接地找到API.


Mat*_*kel 6

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

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

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

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

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

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


小智 6

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

如果你想直截了当地用Python打包,minidom就是你的答案,但它非常蹩脚,而且文档是"这里有关于dom的文档,请详细说明".真的很烦人.

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

我使用过sax系统,在许多方面它们的感觉更加"pythonic",但我通常最终会创建基于状态的系统来处理它们,这就是疯狂(和bug).

如果你喜欢研究,我会说迷你minidom,如果你想要好的代码,我会说ElementTree.


小智 6

我已经将ElementTree用于了几个项目并推荐它.

它是pythonic,带有Python 2.5的"盒子",包括c版cElementTree(xml.etree.cElementTree),它比纯Python版快20倍,并且非常易于使用.

lxml有一些性能优势,但它们不均匀,你应该首先检查你的用例的基准测试.

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


gil*_*tay 6

这取决于文档需要多么复杂.

我已经使用minidom来编写XML,但这通常只是阅读文档,进行一些简单的转换,然后将它们写回来.这很有效,直到我需要能够订购元素属性(以满足一个不能正确解析XML的古老应用程序).那时我自己放弃并写了XML.

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


Jab*_*bba 5

您还可以尝试解开以解析简单的XML文档.


Jan*_*sky 5

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

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

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

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

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

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

来自lxml 文档的有关使用 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>
Run Code Online (Sandbox Code Playgroud)

我很欣赏 E-factory 的以下几点

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

可读性很重要。

允许创建任何 XML 内容

支持以下内容:

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

例如:

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)
Run Code Online (Sandbox Code Playgroud)

导致:

<root>
  <record>alfa</record>
  <record>beta</record>
  <record>gama</record>
</root>
Run Code Online (Sandbox Code Playgroud)

结论

我强烈建议您阅读 lxml 教程 - 它写得非常好,并且会给您更多使用这个强大的库的理由。

lxml 的唯一缺点是它必须被编译。请参阅SO 答案,了解如何在几分之一秒内从 Wheel 格式包安装 lxml 的更多提示。