【问题标题】:Parsing XML with namespace into dictionary将带有命名空间的 XML 解析为字典
【发布时间】:2019-06-20 19:23:11
【问题描述】:

我很难遵循 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. (属性值和文本值)

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

任何建议将不胜感激。

【问题讨论】:

    标签: python xml elementtree


    【解决方案1】:

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

    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)
    

    【讨论】:

    • 完美!谢谢@balderman。剥离命名空间的好主意
    猜你喜欢
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2013-02-01
    • 1970-01-01
    • 2010-11-08
    相关资源
    最近更新 更多