Python中的XML处理


77

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

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

任何人都有使用Python处理XML的经验吗?你会建议我从哪里开始?我将要构建的XML文件将非常简单。


深入Python一章。虽然不能保证会有多好。
伯纳德

4
第一个python问题
Roshan

Answers:


31

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

尤其是对于小的简单内容,我喜欢事件驱动的解析理论,而不是为相对简单的结构设置整个回调系列。 这是有关如何使用API​​的快速讨论

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


Pulldom难道不是解析XML而不生成XML的工具吗(这就是问题所在)?
cunkel

31

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

它是用纯python编写的,正如我所说的,还不错,但是如果您最终需要更高的性能,则lxml公开相同的API并在后台使用libxml2。从理论上讲,您可以在发现需要时将其换入。


1
为了完成您的答案,您是否可以添加lxml还支持XML模式和XPath,而ElementTree不支持?实际上,Python 2.5附带了它。
Torsten Marek

2
ElementTree很好,直到您需要处理名称空间,然后它分崩离析并且无法使用。
Ryu

6

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

如果您想直接使用Python打包,那么minidom是您的答案,但是这很la脚,文档是“这是dom上的文档,请弄清楚”。真烦人。

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

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

我说如果您喜欢研究,可以选择minidom,如果您想要好的代码可以很好地工作,可以选择ElementTree。


在Python中,还有其他方法,例如ElementTree(请参阅Gareth Simpson的回复)
bortzmeyer

6

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

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

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

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


6

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

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

如果您只是在处理简单的文档,那么比学习框架更快,更简单。如果可以想象手动编写XML,那么也可以手动编写XML(只是要记住正确地转义特殊字符并使用str.encode(codec, errors="xmlcharrefreplace"))。除了这些麻烦之外,XML足够普通,以至于您不需要特殊的库来编写它。如果文档太复杂而无法手工编写,那么您可能应该研究一下已经提到的框架之一。您绝对不需要编写通用的XML编写器。



4

由于您提到要构建“非常简单”的XML,因此minidom模块(Python标准库的一部分)可能会满足您的需求。如果您有XML的DOM表示方面的经验,则应该找到非常简单的API。


4

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

对我来说,如果您具有“适合”模式的数据结构,则创建(SOAP)XML文档非常简单。

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

这是使递归变得简单的任务,而我最终得到了正确的结构。这一切都在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的有关使用电子工厂的示例代码(略有简化):


电子工厂为生成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>

我喜欢在电子工厂中进行以下操作

代码几乎读取为生成的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的唯一缺点是必须进行编译。请参阅SO答案以获取更多技巧,如何在不到一秒的时间内从轮式格式软件包安装lxml。


1

如果您要构建SOAP消息,请查看soaplib。它在后台使用ElementTree,但它为序列化和反序列化消息提供了更加简洁的界面。


1

我强烈建议SAX - Simple API for XML-在Python库中实现。它们非常容易设置和处理XML,甚至可以通过驱动来进行处理API,如此处的先前发布者所讨论的那样,并且与验证DOM样式XML解析器不同,它们具有较低的内存占用量。


1

我假设处理XML的.NET方法建立在MSXML的某个版本上,并且在这种情况下,我假设使用minidom将使您感到宾至如归。但是,如果您正在执行的是简单处理,那么任何库都可能会执行。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.