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>
Answers:
ET xpath support is very limited. But this hack should work
roads = root.findall(".//tag[@k='k1']/..") or root.findall(".//tag[@k='k2']/..")
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")
.
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>
ET xpath support is very limited. But this hack should work
roads = root.findall(".//tag[@k='k1']/..") or root.findall(".//tag[@k='k2']/..")
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")
.