24

我喜欢 Python,但我不想仅仅为了从元素中获取属性而写 10 行代码。也许这只是我,但minidom不是这样mini。为了使用它解析某些东西,我必须编写的代码看起来很像 Java 代码。

还有更多的东西user-friendly吗?带有重载运算符的东西,哪些将元素映射到对象?

我希望能够访问这个:


<root>
<node value="30">text</node>
</root>

像这样:


obj = parse(xml_string)
print obj.node.value

而不是使用getChildren或其他类似的方法。

4

4 回答 4

21

你应该看看ElementTree。它并没有完全按照你的意愿做,但它比 minidom 好得多。如果我没记错的话,从 python 2.4 开始,它包含在标准库中。要获得更快的速度,请使用 cElementTree。要获得更快的速度(和更多功能),您可以使用lxml(根据您的需要/方法检查 objectify API)。

我应该补充一点,BeautifulSoup可以部分完成你想要的。Amara也有这种方法。

于 2009-09-29T17:35:42.353 回答
3

我实际上写了一个库,它完全按照你想象的方式做事。该库称为“xe”,您可以从以下位置获取它:http://home.avvanta.com/~steveha/xe.html

xe 可以导入 XML,让您以面向对象的方式处理数据。它实际上使用 xml.dom.minidom 进行解析,但随后它遍历生成的树并将数据打包到 xe 对象中。

编辑:好的,我继续在 xe 中实现了你的例子,所以你可以看到它是如何工作的。以下是实现您展示的 XML 的类:

import xe

class Node(xe.TextElement):
    def __init__(self, text="", value=None):
        xe.TextElement.__init__(self, "node", text)
        if value is not None:
            self.attrs["value"] = value

class Root(xe.NestElement):
    def __init__(self):
        xe.NestElement.__init__(self, "root")
        self.node = Node()

这是使用上述内容的示例。我将您的示例 XML 放入一个名为“example.xml”的文件中,但您也可以将其放入一个字符串中并传递该字符串。

>>> root = Root()
>>> print root
<root/>
>>> root.import_xml("example.xml")
<Root object at 0xb7e0c52c>
>>> print root
<root>
    <node value="30">text</node>
</root>
>>> print root.node.attrs["value"]
30
>>>

请注意,在此示例中,“值”的类型将是字符串。如果你真的需要另一种类型的属性,也可以通过一些工作来实现,但我没有为这个例子费心。(如果您查看 PyFeed,有一个 OPML 类,其属性不是文本。)

于 2009-09-29T18:32:14.877 回答
2

我对简单的 xml 解析器也有同样的需求,经过很长时间检查不同的库后,我发现了 xmltramp

根据您的示例 xml:

import xmltramp

xml_string = """<root>
<node value="30">text</node>
</root>"""

obj = xmltramp.parse(xml_string)
print obj.node('value')             # 30
print str(obj.node)                 # text

我没有发现任何更用户友好的东西。

于 2012-10-05T09:33:23.773 回答
0

我花了很多时间浏览上面提供的示例以及 pip 上列出的存储库。

到目前为止,我发现的最简单(也是最 Pythonic)的解析 XML 的方法是 XMLToDict - https://github.com/martinblech/xmltodict

上面 GitHub 上提供的文档中的示例在下面复制粘贴;很多时候,它让我的生活变得非常简单和容易;

>>> doc = xmltodict.parse("""
... <mydocument has="an attribute">
...   <and>
...     <many>elements</many>
...     <many>more elements</many>
...   </and>
...   <plus a="complex">
...     element as well
...   </plus>
... </mydocument>
... """)
>>>
>>> doc['mydocument']['@has']
u'an attribute'
>>> doc['mydocument']['and']['many']
[u'elements', u'more elements']
>>> doc['mydocument']['plus']['@a']
u'complex'
>>> doc['mydocument']['plus']['#text']
u'element as well'

它工作得非常好,给了我我想要的东西。但是,如果您正在研究反向转换,那将是完全不同的事情。

于 2014-01-07T16:00:25.817 回答