如何使用ElementTree解析XML文件并检索子元素

时间:2013-07-09 09:18:34

标签: xml python-2.7 elementtree

我绞尽脑汁也在Stack Overflow搜索,但似乎我的问题不同。或者也许是我是Python的新手。无论哪种方式,如果你能帮助我,我会非常感激。我有一个XML文件,摘录如下,我需要解析每个元素及其子元素,并将它们保存在dict中。我尝试了很多东西,但是我得到了不同的错误,现在我在我的智慧结束了!

我在下面给出了XML文件,以及我的代码的一个版本(经过试用和错误检索子元素的方法之后大量删除):

<nmwg:message>
    <nmwg:parameters id="storeId">
        <nmwg:parameter name="ID">NameA</nmwg:parameter>
    </nmwg:parameters>

    <!--Metadata and Data-->
    <nmwg:metadata id="md1">
        <nmwg:subject id="subject-port-A">
            <nmwgtopo3:port id="urn:ogf:network:domaina.net:port:A">
                <nmwgtopo3:name type="logical">portA</nmwgtopo3:name>
                <nmwgtopo3:country>COUNTRY</nmwgtopo3:country>              <!--Optional, can be left empty-->
                <nmwgtopo3:city>CITY</nmwgtopo3:city>                       <!--Optional, can be left empty-->
                <nmwgtopo3:institution>INSTITUTION</nmwgtopo3:institution>  <!--Optional, can be left empty-->
                <nmwgtopo3:latitude>LATITUDE</nmwgtopo3:latitude>           <!--Optional, can be left empty-->
                <nmwgtopo3:longitude>LONGTITUDE</nmwgtopo3:longitude>       <!--Optional, can be left empty-->
            </nmwgtopo3:port>
        </nmwg:subject>
    </nmwg:metadata>
    <nmwg:data id="d1" metadataIdRef="md1">
            <ifevt:datum timeType="ISO" timeValue="2006-12-04T16:43:38.0+0000">                
                <ifevt:ifInOctets>integer-number</ifevt:ifInOctets>     <!--Integer number in bytes -->
                <ifevt:ifOutOctets>integer-number</ifevt:ifOutOctets>   <!--Integer number in bytes -->                
            </ifevt:datum>
    </nmwg:data>
</nmwg:message>

这是我的代码:

from __future__ import print_function
from pprint import pprint
import ConfigParser, os
import xml.etree.ElementTree as ET

dataXMLFile = 'xmlFile.xml'
data = ET.parse (dataXMLFile)
root = data.getroot()

for child in root:
    print ('Tag: ' + child.tag)
    print ('Attrib: ' + str(child.attrib))
print()

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}parameters/*')
for item in domainId:
    print ('Tag: ' + item.tag)
    print ('Attrib: ' + str(item.attrib))
print()

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*')
for item in domainId:
    print ('Tag: ' + item.tag)
    print ('Attrib: ' + str(item.attrib))
print()

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*/*')
for item in domainId:
    print ('Tag: ' + item.tag)
        print ('Attrib: ' + str(item.attrib))
print()

domainId = data.findall('{http://ggf.org/ns/nmwg/base/2.0/}metadata/*/*/*')
for item in domainId:
    print ('Tag: ' + item.tag)
    print ('Attrib: ' + str(item.attrib))
print()

我想解析XML文件,以便在portA中获得<nmwgtopo3:name type="logical">值。我试过了,但我只能得到type='logical'位。同样,我想从COUNTRY中提取<nmwgtopo3:country>,从CITY中提取<nmwgtopo3:city>,从<ifevt:ifInOctets>中提取整数(这将是一个正确的整数值),等等。

我更喜欢坚持使用ElementTree而不使用第三方库,并且在上面的问题中感谢您的帮助。

谢谢, Trupsster

1 个答案:

答案 0 :(得分:1)

您正在寻找的是lxml文档中的iterparse / iterwalk文档。

使用iterparse实用程序函数,您可以迭代XML的元素,就像这样:

from lxml import etree
from cStringIO import StringIO

with open('your_file.xml', 'r') as f:
    context = etree.iterparse(StringIO(f.read()))

    for action, element in context:
        print('{0}:{1} {2}'.format(element.tag, element.attrib, element.text))

如果您在XML文件所在的位置运行该代码,您将看到类似于此的输出:

parameter:{'name': 'ID'} NameA
parameters:{'id': 'storeId'}

name:{'type': 'logical'} portA
country:{} COUNTRY
city:{} CITY
institution:{} INSTITUTION
latitude:{} LATITUDE
longitude:{} LONGTITUDE
port:{'id': 'urn:ogf:network:domaina.net:port:A'}

subject:{'id': 'subject-port-A'}

metadata:{'id': 'md1'}

ifInOctets:{} integer-number
ifOutOctets:{} integer-number
datum:{'timeValue': '2006-12-04T16:43:38.0+0000', 'timeType':

所以你可以看到iterparse / iterwalk函数是如何工作的。