首页 > 解决方案 > 如何递归地遍历 xml 文件并访问子节点/元素并使用 Python 存储它们的数据?

问题描述

我有一个如下所示的 XML 文件。现在我需要访问port->name, port->wire->direction, port->wire->driver->defval. XML 文件非常大。

我该如何处理?

<spirit:Bus> 
    <spirit:Ports>   
        <spirit:port>
            <spirit:name>ABCPORT</spirit:name>
            <spirit:description>SOME DESCRIPTION</spirit:description>
            <spirit:wire>
                <spirit:direction>INPUT</spirit:direction>
                <spirit:driver>
                    <spirit:defaultValue>0</spirit:defaultValue>
                </spirit:driver>
            </spirit:wire>
        </spirit:port>
        <spirit:port>
            <spirit:name>PQRPORT</spirit:name>
            <spirit:description>SOME DESCRIPTION</spirit:description>
            <spirit:wire>
                <spirit:direction>OUTPUT</spirit:direction>
            </spirit:wire>
        </spirit:port>        
    </spirit:ports>
</spirit:Bus>

标签: pythonxmlxml-parsingelementtree

解决方案


为了正确格式化 XML,我将命名空间添加到您的示例中:

<spirit:Bus xmlns:spirit="http://dummy.com">
    ...
</spirit:Bus>

但是Bus仍然是根节点,就像您的示例一样。当然,您可以将给定的 URL 更改为您想要的任何内容。

要仅在ElementTree中完成任务,您可以使用以下代码:

import xml.etree.ElementTree as et

tree = et.parse('Input.xml')
root = tree.getroot()
ns = {'spirit': 'http://dummy.com'}
for nd in root.findall('spirit:Ports/spirit:port', ns):
    print(nd.tag.split('}')[1], nd.findtext('spirit:name', namespaces=ns),
        nd.findtext('spirit:wire/spirit:direction', namespaces=ns),
        nd.findtext('spirit:wire/spirit:driver/spirit:defaultValue', namespaces=ns))

请注意,您的 XML 包含命名空间规范,因此您还必须在代码中指定它。

我的代码还显示了如何获取节点的本地名称(没有命名空间)。

结果,对于您的样本是:

port ABCPORT INPUT 0
port PQRPORT OUTPUT None

推荐阅读