【问题标题】:Access nested children in xml file parsed with ElementTree访问使用 ElementTree 解析的 xml 文件中的嵌套子项
【发布时间】: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

为什么会这样?

【问题讨论】:

    标签: python xml tree xml-parsing elementtree


    【解决方案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__()
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多