有没有考虑人类使用的Python XML解析器?

24 投票
4 回答
5733 浏览
提问于 2025-04-15 14:41

我喜欢Python,但我不想为了从一个元素中获取一个属性而写10行代码。也许只是我个人的感觉,但minidom并没有那么“迷你”。我用它解析东西时写的代码,看起来很像Java的代码。

有没有什么更“用户友好”的东西?比如说,有重载操作符的,能把元素映射到对象上的?

我想要能够像这样访问:


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

而不是像这样:


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

而且不想用getChildren或者其他类似的方法。

4 个回答

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

我没有找到比这个更容易使用的了。

3

其实我写了一个库,正好可以实现你想要的功能。这个库叫做“xe”,你可以在这里找到它:http://home.avvanta.com/~steveha/xe.html

xe可以导入XML文件,这样你就可以用面向对象的方式来处理数据。它实际上是用xml.dom.minidom来解析XML,然后再遍历解析出来的树,把数据装进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
>>>

需要注意的是,在这个例子中,“value”的类型将是字符串。如果你真的需要其他类型的属性,也可以做到,只是需要多花点功夫,但我在这个例子中就没做了。(如果你看看PyFeed,会发现有一个OPML类,它有一个不是文本的属性。)

21

你可以看看 ElementTree。虽然它不完全符合你的需求,但比起minidom要好很多。如果我没记错的话,从Python 2.4开始,它就已经包含在标准库里了。如果你想要更快的速度,可以使用cElementTree。如果你需要更快的速度和更多的功能,可以试试 lxml(可以查看objectify API来满足你的需求)。

我还要补充一下,BeautifulSoup也能部分满足你的需求。另外,还有一个叫 Amara 的工具,也有类似的功能。

撰写回答