Python ElementTree XPath multiple conditions for attributes

Question:

I’m trying to select nodes from my XML by the following rules:

parent of node named "tag" with attributes k=’k1′ and (v=’v1′ or v=’v2′)

How can I achieve it using python and ElementTree? I tried the following code, but got an error "SyntaxError: invalid predicate"

roads = root.findall(".//tag[@k='k1'][@v='v1' or @v='v2']/..")
roads = root.findall(".//tag[@k='k1' and (@v='v1' or @v='v2')]/..")

UPDATE

XML sample

<parent>
  <tag k="k1" v="v1"/>
  <tag k="k1" v="v2"/>
  <tag k="k1" v="v3"/>
 </parent>
Asked By: Nikita Fedorov

||

Answers:

ET xpath support is very limited. But this hack should work

roads = root.findall(".//tag[@k='k1']/..") or root.findall(".//tag[@k='k2']/..") 
Answered By: Jack Fleeting

You can definitely do this, but it seems like XPath isn’t the way to go about filtering for the right attributes.

roads = [el for el in root.findall(".//tag") if el.attrib["k"] == "k1" and el.attrib["v"] in ("v1", "v2")]

If it makes it clearer, the logic can be rewritten as el.attrib["k"] == "k1" and (el.attrib["v"] == "v1" or el.attrib["v"] == "v2").

Answered By: Sunny A
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.