访问使用 ElementTree 解析的 xml 文件中的嵌套子项

Posted

技术标签:

【中文标题】访问使用 ElementTree 解析的 xml 文件中的嵌套子项【英文标题】:Access nested children in xml file parsed with ElementTree 【发布时间】:2017-10-10 19:11:57 【问题描述】:

我是 xml 解析的新手。 This xml file 具有以下树:

FHRSEstablishment
 |--> Header
 |    |--> ...
 |--> EstablishmentCollection
 |    |--> EstablishmentDetail
 |    |    |-->...
 |    |--> Scores
 |    |    |-->...
 |--> EstablishmentCollection
 |    |--> EstablishmentDetail
 |    |    |-->...
 |    |--> Scores
 |    |    |-->...

但是当我使用 ElementTree 访问它并查找 child 标记和属性时,

import xml.etree.ElementTree as ET
import urllib2
tree = ET.parse(
   file=urllib2.urlopen('http://ratings.food.gov.uk/OpenDataFiles/FHRS408en-GB.xml' % i))
root = tree.getroot()
for child in root:
   print child.tag, child.attrib

我只得到:

Header 
EstablishmentCollection 

我认为这意味着它们的属性是空的。为什么会这样,我如何访问嵌套在 EstablishmentDetailScores 中的孩子?

编辑

感谢下面的答案,我可以进入树内部,但如果我想检索诸如 Scores 中的值,则失败:

for node in root.find('.//EstablishmentDetail/Scores'):
    rating = node.attrib.get('Hygiene')
    print rating 

并产生

None
None
None

为什么会这样?

【问题讨论】:

【参考方案1】:

你必须在你的根目录上进行 iter()。

root.iter() 可以解决问题!

import xml.etree.ElementTree as ET
import urllib2
tree =ET.parse(urllib2.urlopen('http://ratings.food.gov.uk/OpenDataFiles/FHRS408en-GB.xml'))
root = tree.getroot()
for child in root.iter():
   print child.tag, child.attrib

输出:

FHRSEstablishment 
Header 
ExtractDate 
ItemCount 
ReturnCode 
EstablishmentCollection 
EstablishmentDetail 
FHRSID 
LocalAuthorityBusinessID 
...
要获取EstablishmentDetail 中的所有标签,您需要找到该标签,然后遍历其子标签!

例如。

for child in root.find('.//EstablishmentDetail'):
    print child.tag, child.attrib

输出:

FHRSID 
LocalAuthorityBusinessID 
BusinessName 
BusinessType 
BusinessTypeID 
RatingValue 
RatingKey 
RatingDate 
LocalAuthorityCode 
LocalAuthorityName 
LocalAuthorityWebSite 
LocalAuthorityEmailAddress 
Scores 
SchemeType 
NewRatingPending 
Geocode 
要获得您在评论中提到的Hygiene 的分数,

您所做的是,它将获得第一个 Scores 标签,当您调用 for each in root.find('.//Scores'):rating=child.get('Hygiene') 时,它将具有 Hygiene、ConfidenceInManagement、Structural 标签作为子标签。也就是说,显然所有三个孩子都不会有元素!

你需要先 - 找到所有Scores 标签。 - 在找到的每个标签中找到Hygiene

for each in root.findall('.//Scores'):
    rating = each.find('.//Hygiene')
    print '' if rating is None else rating.text

输出:

5
5
5
0
5

【讨论】:

哇,这很好,但我仍然难以获得最终值,例如分数。如果我这样做for child in root.find('.//Scores'): rating = child.get('Hygiene'); print rating;,我会得到None .// 是做什么的?这是正则表达式吗?【参考方案2】:

希望它有用:

import xml.etree.ElementTree as etree
with open('filename.xml') as tmpfile:
    doc = etree.iterparse(tmpfile, events=("start", "end"))
    doc = iter(doc)
    event, root = doc.next()
    num = 0
    for event, elem in doc:
        print event, elem

【讨论】:

event, root = doc.next()AttributeError: 'IterParseIterator' object has no attribute 'next' 我的脚本适用于 python2,供 python3 使用:event, root = doc.__next__()

以上是关于访问使用 ElementTree 解析的 xml 文件中的嵌套子项的主要内容,如果未能解决你的问题,请参考以下文章

python使用ElementTree解析XML文件

使用 ElementTree 示例在 Python 中解析 XML

使用Python和ElementTree解析XML

python 使用ElementTree解析xml

python解析xml文件之xml.etree.cElementTree和xml.etree.ElementTree区别

如何使用 python xml.etree.ElementTree 解析 eBay API 响应?