在Python中使用lxml遍历XML的最快/最佳方法

1 投票
1 回答
3238 浏览
提问于 2025-04-17 08:34

我有一个看起来像这样的XML文件:

xml = '''<?xml version="1.0"?>
        <root>
            <item>text</item>
            <item2>more text</item2>
            <targetroot>
                <targetcontainer>
                    <target>text i want to get</target>
                </targetcontainer>
                <targetcontainer>
                    <target>text i want to get</target>
                </targetcontainer>
            </targetroot>
            ...more items
        </root>
'''

我正在用lxml库尝试访问< target >这个元素里的文本。我找到了一种解决办法,但我觉得肯定还有更好、更有效的方法。我的解决办法是:

target = etree.XML(xml)

for x in target.getiterator('root'):
    item1 = x.findtext('item')
    for target in x.iterchildren('targetroot'):
        for t in target.iterchildren('targetcontainer'):
            targetText = t.findtext('target')

虽然这个方法有效,因为它让我可以访问根元素下的所有元素以及目标元素,但我还是觉得这不是最有效的解决方案。

所以我想问的是:有没有更有效的方法可以在遍历根元素的同时访问< target >的文本,因为我还需要访问其他元素。

1 个回答

3

你可以使用 XPath 来处理这个问题:

for x in target.xpath('/root/targetroot/targetcontainer/target'):
    print x.text

我们在寻找符合特定路径的所有元素。在这个例子中,路径是 /root/targetroot/targetcontainer/target,这意味着:

所有在 <targetcontainer> 元素里的 <target> 元素,而这个 <targetcontainer> 又是在 <targetroot> 元素里,而这个 <targetroot> 又是在 <root> 元素里。并且,<root> 元素应该是文档的根元素,因为它前面有一个 /,这表示文档的开始。

另外,你的 XML 文档有两个问题。首先,<?xml version="1.0"?> 声明应该是文档中的第一行 - 在这个例子里,它前面有一个换行和一些空格。而且,这不是一个标签,不需要关闭,所以你字符串末尾的 </xml> 应该去掉。反正我已经编辑过你的问题了。

编辑:这个解决方案还有改进的空间。你不需要写出完整的路径 - 你可以只请求文档中所有的 <target> 元素。只需在标签名前加两个斜杠就可以了。因为你想要的是所有的 target 文本,不管它们在哪里,这样的方式会更好。所以,上面的循环可以简化为:

for x in target.xpath('//target'):
    print x.text

我一开始试过这个,但没有成功。问题其实出在 XML 的语法上,而不是 XPath。我试了另一个更长的路径,结果忘了再试这个。抱歉!不过,我希望我能让你对 XPath 有一些了解 :)

撰写回答