Python 中的 XML 处理
Posted
技术标签:
【中文标题】Python 中的 XML 处理【英文标题】:XML Processing in Python 【发布时间】:2010-09-05 05:55:27 【问题描述】:我将要构建一个项目的一部分,该项目需要构建 XML 文档并将其发布到 Web 服务,我想用 Python 来完成它,以扩展我的技能。
不幸的是,虽然我非常了解 .NET 中的 XML 模型,但我不确定 Python 中的 XML 模型的优缺点是什么。
任何人都有在 Python 中进行 XML 处理的经验吗?你建议我从哪里开始?我将要构建的 XML 文件将相当简单。
【问题讨论】:
Dive Into Python 有一个章节。但不能保证它会有多好。 第一个python问题 【参考方案1】:我假设 .NET 处理 XML 的方式是建立在某个版本的 MSXML 之上的,在这种情况下,我假设使用 minidom 等工具会让您有宾至如归的感觉。但是,如果您正在进行简单的处理,任何库都可能会这样做。
在 Python 中处理 XML 时,我也更喜欢使用 ElementTree,因为它是一个非常简洁的库。
【讨论】:
【参考方案2】:我编写了一个接收 XML 请求并创建 XML 响应的 SOAP 服务器。 (很遗憾,这不是我的项目,所以它是闭源的,但这是另一个问题)。
对我来说,如果您有一个“适合”架构的数据结构,那么创建 (SOAP) XML 文档是相当简单的。
我保留信封,因为响应信封(几乎)与请求信封相同。然后,由于我的数据结构是一个(可能是嵌套的)字典,我创建了一个字符串,将该字典转换为
这是一个递归简化的任务,我最终得到了正确的结构。这一切都是在 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 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: <spam&egg>.</p>
</body>
</html>
我很欣赏 E-factory 它遵循的东西
代码读取几乎与生成的 XML 文档一样
可读性很重要。
允许创建任何 XML 内容
支持以下内容:
命名空间的使用 一个元素内的开始和结束文本节点 函数格式化属性内容(参见full lxml sample中的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 answer for more tips 如何在几分之一秒内从 wheel 格式包中安装 lxml。
【讨论】:
【参考方案4】:我强烈推荐SAX - Simple API for XML
- 在 Python 库中实现。它们相当容易设置和处理大型XML
,甚至驱动API
,正如之前的海报所讨论的那样,并且与验证DOM
样式XML
解析器不同,它们具有较低的内存占用。
【讨论】:
【参考方案5】:您也可以尝试untangle 来解析简单的 XML 文档。
【讨论】:
【参考方案6】:这在一定程度上取决于文档需要有多复杂。
我在编写 XML 时经常使用 minidom,但通常只是读取文档,进行一些简单的转换,然后将它们写回。直到我需要对元素属性进行排序的能力(以满足不能正确解析 XML 的古老应用程序)之前,这已经足够好用了。那时我放弃了,自己编写了 XML。
如果您只处理简单的文档,那么自己动手会比学习框架更快、更简单。如果您可以想象手动编写 XML,那么您也可以手动编写它(只要记住正确转义特殊字符,并使用 str.encode(codec, errors="xmlcharrefreplace")
)。除了这些混乱之外,XML 足够规则,您不需要一个特殊的库来编写它。如果文档太复杂而无法手动编写,那么您可能应该查看已经提到的框架之一。任何时候都不需要编写通用的 XML 编写器。
【讨论】:
【参考方案7】:如果您要构建 SOAP 消息,请查看 soaplib。它在底层使用 ElementTree,但它为序列化和反序列化消息提供了更简洁的接口。
【讨论】:
【参考方案8】:我在几个项目中使用过 ElementTree 并推荐它。
它是 Python 的,随 Python 2.5 提供,包括 c 版本的 cElementTree (xml.etree.cElementTree),它比纯 Python 版本快 20 倍,并且非常易于使用。
lxml 具有一些性能优势,但它们并不均衡,您应该首先检查您的用例的基准。
据我了解,ElementTree 代码可以轻松移植到 lxml。
【讨论】:
【参考方案9】:通常有 3 种主要的处理 XML 的方法:dom、sax 和 xpath。如果您有能力一次将整个 xml 文件加载到内存中,并且您不介意处理数据结构,并且您正在查看大部分/大部分模型,则 dom 模型很好。如果您只关心几个标签,并且/或者您正在处理大文件并且可以按顺序处理它们,那么 sax 模型非常棒。 xpath 模型各有不同——您可以选择所需数据元素的路径,但它需要使用更多库。
如果你想直接使用 Python 打包,minidom 是你的答案,但它很蹩脚,文档是“这里是 dom 上的文档,去弄清楚”。真的很烦。
就我个人而言,我喜欢 cElementTree,它是 ElementTree 的一个更快(基于 c 的)实现,它是一个类似 dom 的模型。
我使用过 sax 系统,并且在很多方面它们的感觉更像是“pythonic”,但我通常最终会创建基于状态的系统来处理它们,而这就是疯狂(和错误)。
如果你喜欢研究,我说使用 minidom,如果你想要运行良好的好代码,我说使用 ElementTree。
【讨论】:
在Python中,还有其他方式,比如ElementTree(见Gareth Simpson的回复)【参考方案10】:由于您提到您将构建“相当简单”的 XML,minidom module(Python 标准库的一部分)可能会满足您的需求。如果您对 XML 的 DOM 表示有任何经验,您应该会发现 API 非常简单。
【讨论】:
【参考方案11】:ElementTree 有一个不错的 pythony API。我认为它甚至是作为 python 2.5 的一部分发布的
它是在纯 python 中,正如我所说,非常好,但如果你最终需要更高的性能,那么lxml 会公开相同的 API 并在后台使用 libxml2。理论上,您可以在发现需要时将其换掉。
【讨论】:
为了完成你的答案,你能补充一下 lxml 还支持 XML 模式和 XPath,ElementTree 不支持吗?它确实随 Python 2.5 一起提供。 ElementTree 在你需要处理命名空间之前很好,然后它就会崩溃并且无法使用。【参考方案12】:就个人而言,我在一个 XML 繁重的项目中使用了几个内置选项,并确定 pulldom 作为不太复杂的文档的最佳选择。
特别是对于简单的小东西,我喜欢事件驱动的解析理论,而不是为一个相对简单的结构设置一整套回调。 Here is a good quick discussion of how to use the API.
我喜欢的是:您可以在 for
循环中处理解析,而不是使用回调。您还延迟了完整解析(“拉”部分),并且只有在您调用 expandNode()
时才能获得更多详细信息。这在不牺牲易用性和简单性的情况下满足了我对“负责任”效率的一般要求。
【讨论】:
难道 pulldom 不是解析 XML 的工具,而不是生成它(这是问题要问的)?以上是关于Python 中的 XML 处理的主要内容,如果未能解决你的问题,请参考以下文章