将具有命名空间的 XML 解析为字典



我很难遵循xml.etree.ElementTree文档,以解析具有命名空间和嵌套标签的XML文档。

首先,我尝试解析的 xml 树如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ROOT-MAIN xmlns="http://fakeurl.com/page">
    <Alarm> <--- I dont care about these types of objects
        <Node>
            <location>Texas></location>
            <name>John</name>
        </Node>
    </Alarm>
    <Alarm> <--- I care about these types of objects
        <CreateTime>01/01/2011</CreateTime>
        <Story>
            <Node>
                <Name>Ethan</name
                <Address category="residential>
                    <address>1421 Morning SE</address>
                </address>
            </Node>
        </Story>
        <Build>
            <Action category="build_value_1">Build was successful</Action>
        </Build>
        <OtherData type="string" meaning="favoriteTVShow">Purple</OtherData>
        <OtherData type="string" meaning="favoriteColor">Seinfeld</OtherData>
    </Alarm>
</ROOT-MAIN>

我正在尝试构建一个字典数组,这些字典的结构与第二个对象相似。解析此 XML 文件时,我执行以下操作:

import xml.etree.ElementTree as ET
tree = ET.parse('data/'+filename)
root = tree.getroot()

namespace= '{http://fakeurl.com/page}'
for alarm in tree.findall(namespace+'Alarm'):
    for elem in alarm.iter():
        try:
            creation_time = elem.find(namespace+'CreateTime')
            for story in elem.findall(namespace+'Story'):
                for node in story.findall(namespace+'Node'):
                    for Address in node.findall(namespace+'Address'):
                        address = Address.find(namespace+'address').text
            for build in elem.findall(namespace+'Build'):
                category= build.find(namespace+'Action').attrib
                action = build.find(namespace+'Action').text
            
            for otherdata in elem.findall(namespace+'OtherData'):
                #not sure how to get the 'meaning' attribute value as well as the text value for these <OtherData> tags  
        except:
            pass

是的,我只是想获取以下值:

  1. <地址>
  2. <操作>(属性值和文本值(
  3. <其他数据>(属性值和文本值(

我有点能够使用 for 循环中的 for 循环来做到这一点,但我希望有一个更干净的 xpath 解决方案,但我还没有弄清楚如何处理命名空间。

任何建议将不胜感激。

在这里(收集你提到的元素的子集 - 添加更多代码来收集其余元素(

import xml.etree.ElementTree as ET
import re
xmlstring = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://fakeurl.com/page">
    <Alarm> 
        <Node>
            <location>Texas></location>
            <name>John</name>
        </Node>
    </Alarm>
    <Alarm> 
        <CreateTime>01/01/2011</CreateTime>
        <Story>
            <Node>
                <Name>Ethan</Name>
                <Address category="residential">
                    <address>1421 Morning SE</address>
                </Address>
            </Node>
        </Story>
        <Build>
            <Action category="build_value_1">Build was successful</Action>
        </Build>
        <OtherData type="string" meaning="favoriteTVShow">Purple</OtherData>
        <OtherData type="string" meaning="favoriteColor">Seinfeld</OtherData>
    </Alarm>
</root>'''
xmlstring = re.sub(' xmlns="[^"]+"', '', xmlstring, count=1)
root = ET.fromstring(xmlstring)
alarms = root.findall('Alarm')
alarms_list = []
for alarm in alarms:
    create_time = alarm.find('CreateTime')
    if create_time is not None:
        entry = {'create_time': create_time.text}
        alarms_list.append(entry)
        actions = alarm.findall('Build/Action')
        if actions:
            entry['builds'] = []
        for action in actions:
            entry['builds'].append({'category': action.attrib['category'], 'status': action.text})
print(alarms_list)

最新更新