繁体   English   中英

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

[英]Parsing XML with namespace into dictionary

对于解析带有名称空间和嵌套标记的XML文档,我很难遵循xml.etree.ElementTree文档。

首先,我要解析的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>

我正在尝试构建一个字典数组,该字典的结构与第二个<Alarm>对象类似。 解析此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. <OtherData>(属性值和文本值)

我可以使用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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM