使用 ElementTree 递归地获取 xml 标签值

Fetch xml tag values recursively using ElementTree

我有一个类型的 xmk:

<SCHOOL>
    <GROUP name="GetStudInfo">

        <DATA>
            <NAME type="char">Sahil Jha</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Rashmi Kaur</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Palak Bisht</NAME>
            <STD>11th</STD>
        </DATA>
</SCHOOL>

我需要获取 NAME、STD 的值。 我试过这样做:

e = ET.ElementTree(ET.fromstring(getunitinfo_str))
    for elt in e.iter():
        print("{} {}".format(elt.tag, elt.text))

但这也涵盖了其他值: 输出:

SCHOOL

GROUP


DATA

NAME Sahil Jha
STD 11th
DATA

NAME Rashmi Kaur
STD 11th
DATA

NAME Palak Bisht
STD 11th
{}

预期 O/p:

{'Sahil Jha':'11th', 'Rashmi Kaur'::'11th', 'Palak Bisht':'11th'}

但格式应为 NAME:STD 类型。我哪里错了?

如@furas 所述,您可以使用 XPATH 查找所有 DATA 元素,然后找到 NAMESTD 元素:


import xml.etree.ElementTree as ET

xml = '''<SCHOOL>
    <GROUP name="GetStudInfo">

        <DATA>
            <NAME type="char">Sahil Jha</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Rashmi Kaur</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Palak Bisht</NAME>
            <STD>11th</STD>
        </DATA>
</GROUP>
</SCHOOL>'''


e = ET.fromstring(xml)
for data_tag in e.findall('DATA'):
    name = data_tag.find('NAME')
    std = data_tag.find('STD')
    print("{} {}".format(name.text, std.text))

或者你可以使用字典理解来获取你想要的字典:

my_dict = {
    data_tag.find('NAME').text: data_tag.find('STD').text
    for data_tag in e.findall('.//DATA')
}
print(my_dict)

你需要的不仅仅是 print() - 你需要 if/else 检查 elt.tag 才能得到 NAME 和 `STD.

因为 NAMESTD 是不同的标签所以你必须记住 NAME 在一些变量中当你得到 STD

时使用它
name = None  # default value at start

for elt in e.iter():
    if elt.tag == 'NAME':
        name = elt  # remember element
    if elt.tag == 'STD':
        print("{}:{}".format(name.text, elt.text))

或者你可以像@qouify 的回答那样使用 xpath


最少的工作代码

getunitinfo_str = '''
<SCHOOL>
    <GROUP name="GetStudInfo">

        <DATA>
            <NAME type="char">Sahil Jha</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Rashmi Kaur</NAME>
            <STD>11th</STD>
        </DATA>

        <DATA>
            <NAME type="char">Palak Bisht</NAME>
            <STD>11th</STD>
        </DATA>
    </GROUP>
</SCHOOL>
'''

import xml.etree.ElementTree  as ET

e = ET.ElementTree(ET.fromstring(getunitinfo_str))

name = None # to remeber element

for elt in e.iter():
    if elt.tag == 'NAME':
        name = elt
    if elt.tag == 'STD':
       print("{}:{}".format(name.text, elt.text))

下面一层

import xml.etree.ElementTree as ET

xml = '''<SCHOOL>
    <GROUP name="GetStudInfo">
        <DATA>
            <NAME type="char">Sahil Jha</NAME>
            <STD>11th</STD>
        </DATA>
        <DATA>
            <NAME type="char">Rashmi Kaur</NAME>
            <STD>116th</STD>
        </DATA>
        <DATA>
            <NAME type="char">Palak Bisht</NAME>
            <STD>17th</STD>
        </DATA>
</GROUP>
</SCHOOL>'''

root = ET.fromstring(xml)
data = {x.find("NAME").text: x.find("STD").text for x in root.findall('.//DATA')}
print(data)

输出

{'Sahil Jha': '11th', 'Rashmi Kaur': '116th', 'Palak Bisht': '17th'}