简体   繁体   English

如何获取具有特定标签和属性的子元素的 xml 元素

[英]How to get xml elements which have childs with a certain tag and attribute

I want to find xml elements which have certain child elements.我想找到具有某些子元素的 xml 元素。 The child elements need to have a given tag and an attribute set to a specific value.子元素需要有一个给定的标签和一个设置为特定值的属性。

To give a concrete example (based on the official documentation ).举一个具体的例子(根据官方文档)。 I want to find all country elements which have a child element neighbor with attribute name="Austria" :我想找到所有具有属性name="Austria"的子元素neighborcountry元素:

import xml.etree.ElementTree as ET

data = """<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <neighbor name="Malaysia" direction="N"/>
        <partner name="Austria"/>
    </country>
    <country name="Panama">
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
"""

root = ET.fromstring(data)

What I've tried without success:我没有成功的尝试:

countries1 = root.findall('.//country[neighbor@name="Austria"]')
countries2 = root.findall('.//country[neighbor][@name="Austria"]')
countries3 = root.findall('.//country[neighbor[@name="Austria"]]')

which all give:这都给了:

SyntaxError: invalid predicate SyntaxError:无效谓词


Following solutions are obviously wrong, as too much elements are found:以下解决方案显然是错误的,因为发现了太多元素:

countries4 = root.findall('.//country/*[@name="Austria"]')
countries5 = root.findall('.//country/[neighbor]')

where countries4 contains all elements having an attribute name="Austria" , but including the partner element.其中countries4包含所有具有属性name="Austria"的元素,但包括partner元素。 countries5 contains all elements which have any neighbor element as a child. countries5包含所有具有任何相邻元素作为子元素的元素。

I want to find all country elements which have a child element neighbor with attribute name="Austria"我想找到所有具有属性 name="Austria" 的子元素邻居的国家元素

see below见下文

import xml.etree.ElementTree as ET

data = """<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <neighbor name="Malaysia" direction="N"/>
        <partner name="Austria"/>
    </country>
    <country name="Panama">
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
"""

root = ET.fromstring(data)
countries_with_austria_as_neighbor = [c.attrib['name'] for c in root.findall('.//country') if
                                      'Austria' in [n.attrib['name'] for n in c.findall('neighbor')]]
print(countries_with_austria_as_neighbor)

output output

['Liechtenstein']
import xml.etree.ElementTree as ET

data = """<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <neighbor name="Malaysia" direction="N"/>
        <partner name="Austria"/>
    </country>
    <country name="Panama">
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
    <country name="Liechtenstein">
        <neighbor name="Austria" direction="dummy"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    
</data>
"""

root = ET.fromstring(data)
for x in root.findall(".//country/neighbor[@name='Austria']"):
    print(x.attrib)

Output: Output:

{'name': 'Austria', 'direction': 'E'}
{'name': 'Austria', 'direction': 'dummy'}

// : Selects all subelements, on all levels beneath the current element. For example, .//egg selects all egg elements in the entire tree. // : Selects all subelements, on all levels beneath the current element. For example, .//egg selects all egg elements in the entire tree. Selects all subelements, on all levels beneath the current element. For example, .//egg selects all egg elements in the entire tree.

[@attrib='value'] : Selects all elements for which the given attribute has the given value. The value cannot contain quotes [@attrib='value']Selects all elements for which the given attribute has the given value. The value cannot contain quotes Selects all elements for which the given attribute has the given value. The value cannot contain quotes

for x in root.find('.'):
    if x[0].attrib['name'] == 'Austria':
                   print(x.attrib['name']) 

Output: Liechtenstein Output: Liechtenstein

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM