[英]How to test for existence of child nodes using Python to iterate over XML (using xml.dom.minidom)
[英]How do I iterate over a xml file recursively and access the child nodes/elements and store their data using 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>
我相信解決這個問題的最好方法是使用 lxml 和 xpath:
from lxml import etree
#the xml below is somewhat different than the one in the question, because of a type and the declare namespaces
spirit = """<?xml version="1.0" encoding="UTF-8"?>
<doc xmlns:spirit="http://example.com">
<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>
</doc>
"""
doc = etree.XML(spirit.encode('utf-8'))
ports = doc.xpath('//*[local-name()="port"]')
for port in ports:
try:
print("Port-",port.xpath('.//*[local-name()="name"]')[0].text)
print("Direction",port.xpath('.//*[local-name()="direction"]')[0].text)
print("Default value",port.xpath('.//*[local-name()="defaultValue"]')[0].text)
except:
continue
Output:
Port- ABCPORT
Direction INPUT
Default value 0
Port- PQRPORT
Direction OUTPUT
為了正確格式化 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.