访问使用 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
我认为这意味着它们的属性是空的。为什么会这样,我如何访问嵌套在 EstablishmentDetail
和 Scores
中的孩子?
编辑
感谢下面的答案,我可以进入树内部,但如果我想检索诸如 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 文件中的嵌套子项的主要内容,如果未能解决你的问题,请参考以下文章
使用 ElementTree 示例在 Python 中解析 XML
python解析xml文件之xml.etree.cElementTree和xml.etree.ElementTree区别