Lọc phần tử Python bằng XPath

Sep 04 2020

hãy tưởng tượng tôi có một XML như thế này:

<root>
  <elements>
    <element> foo </element>
    <element is="false"> foo </element>
    <element is="false"> bli </element>
    <element is="false"> bla </element>
  </elements>
</root>

Tôi có thể làm cái này như thế nào:

import xml.etree.ElementTree as ET

root = ET.fromstring(XmlFromAbove)
res_a  = root.findall("element[@is='false']")) ##<- This gives me all elements with the specific attribute
res_b  = root.findall("element[not@is='false']")) ##<- This would be nice to give me all elements without that specific attribute (`<element> foo </element>` in this case)

Bây giờ, tôi biết điều đó res_bsẽ không hiệu quả nhưng tôi đoán đây là một vấn đề phổ biến nên bất kỳ ai cũng có ý tưởng về cách giải quyết đó là gì?

Để chỉ ra nó nhiều hơn một chút (sao chép từ các nhận xét)

Tôi có thể tìm thấy phần tử chứa "foo" nhưng điều tôi muốn biết là liệu có cách nào để tìm bất kỳ phần tử nào KHÔNG chứa thuộc tính is = "false" hay không.

Trả lời

2 balderman Sep 04 2020 at 17:10

xem bên dưới

import xml.etree.ElementTree as ET

xml = '''<root>
  <elements>
    <element> foo </element>
    <element is="false"> foo </element>
    <element is="false"> bli </element>
    <element is="false"> bla </element>
    <element please="false"> no_is </element>
    <element is="true"> with_true_is </element>
  </elements>
</root>'''

root = ET.fromstring(xml)

no_is_lst = [e for e in root.findall('.//element') if 'is' not in e.attrib]
for e in no_is_lst:
    print(e.text)

đầu ra

 foo 
 no_is 
deadshot Sep 04 2020 at 16:59

Bạn có thể sử dụng lxml

from lxml import etree

root = etree.fromstring(data)
res = root.xpath(".//element[not(@is)]")

print(res[0].text) #foo