user2015487
user2015487

Reputation: 2185

XPATH selecting the root and all descendents elements with a specific attribute in python

I want to grab all elements that have the attribute x in them including the root node. What I currently have is that it works except it does not include the root node. As you can see from the print out, it selects B and Ca elements. However, the output should include A as well, i.e. [Element A, Element B, Element Ca]. How can I make it grab the root node as well?

from lxml import etree as ET
expr='''
<A x="1">
    <B z="1">
        <C  y="1"/>
    </B>
    <B x="1">
        <Ca  x="1" y="2"/>
    </B>
</A>

'''
expr_root=ET.fromstring(expr)
print(expr_root.findall(".//*[@x]")) #[<Element B at 0xd0118c8>, <Element Ca at 0xd011b48>]

Upvotes: 1

Views: 444

Answers (2)

Sachin
Sachin

Reputation: 219

You can try "//[@A]", it will select all elements that have attribute A. In your case "//[@x]".

Hope it will help.

Upvotes: 0

alecxe
alecxe

Reputation: 473853

You can use descendant-or-self:

expr_root.xpath(".//descendant-or-self::*[@x]")

Demo:

In [1]: from lxml import etree as ET

In [2]: expr = '''
   ...: <A x="1">
   ...:     <B z="1">
   ...:         <C  y="1"/>
   ...:     </B>
   ...:     <B x="1">
   ...:         <Ca  x="1" y="2"/>
   ...:     </B>
   ...: </A>
   ...: '''

In [3]: expr_root = ET.fromstring(expr)

In [4]: print(expr_root.xpath(".//descendant-or-self::*[@x]"))
[<Element A at 0x1045675c8>, <Element B at 0x105de1688>, <Element Ca at 0x105de0548>]

Upvotes: 1

Related Questions