Python中的XML处理

时间:2008-08-02 03:35:56

标签: python xml

我即将构建一个需要构建XML文档并将其发布到Web服务的项目,我希望用Python来实现,以此来扩展我的技能。

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

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

12 个答案:

答案 0 :(得分:31)

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

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

答案 1 :(得分:28)

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

特别是对于简单的小东西,我喜欢事件驱动的解析理论,而不是为一个相对简单的结构设置一大堆回调。 Here is a good quick discussion of how to use the API

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

答案 2 :(得分:6)

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

如果你想直接使用Python打包,minidom就是你的答案,但它非常蹩脚,而且文档是“这里有关于dom的文档,请详细说明”。真的很烦人。

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

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

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

答案 3 :(得分:6)

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

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

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

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

答案 4 :(得分:6)

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

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

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

答案 5 :(得分:5)

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

答案 6 :(得分:4)

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

答案 7 :(得分:4)

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

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

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

这是递归变得简单的任务,我最终得到了正确的结构。这都是在python代码中完成的,目前足够快,可以用于生产。

你也可以(相对)轻松地建立列表,虽然取决于你的客户,你可能遇到问题,除非你给出长度提示。

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

答案 8 :(得分:3)

要在Python中使用XML进行认真的工作,请使用lxml

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

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

使用E-factory(来自lxml)

构建XML文档

您的问题是关于构建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>

我很欣赏电子工厂的事情

代码几乎读取为生成的XML文档

可读性很重要。

允许创建任何XML内容

支持以下内容:

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

允许包含列表

的非常易读的结构

e.g:

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。

答案 9 :(得分:1)

我认为处理XML的.Net方式建立在某些版本的MSXML之上,在这种情况下我假设使用例如minidom会让你感觉有点在家。但是,如果它是简单的处理,你可能会做任何库。

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

答案 10 :(得分:1)

如果您要构建SOAP消息,请查看soaplib。它使用了引擎盖下的ElementTree,但它为序列化和反序列化消息提供了更清晰的界面。

答案 11 :(得分:1)

我强烈推荐SAX - Simple API for XML - 在Python库中实现。它们很容易设置和处理大型XML甚至被驱动API,正如之前的海报所讨论的那样,并且与验证DOM样式XML解析器不同,内存占用率低。