sneg
sneg

Reputation: 2216

Python lxml: how to get human-readable XPath for XML element?

I have a short XML document:

<tag1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns="http://example.com/2009/namespace">
    <tag2>
        <tag3/>
        <tag3/>
    </tag2>
</tag1>

A short Python program loads this XML file like this:

from lxml import etree

f = open( 'myxml.xml' )
tree = etree.parse(f)
MY_NAMESPACE = 'http://example.com/2009/namespace'
xpath = etree.XPath( '/f:tag1/f:tag2/f:tag3', namespaces = { 'f': MY_NAMESPACE } )
# get first element that matches xpath
elem = xpath(tree)[0]
# get xpath for an element 
print tree.getpath(elem)

I am expecting to get a meaningful, human-readable xpath with this code, however, instead I get a string like /*/*/*[1].

Any idea what could be causing this and how I can diagnose this issue?

Note: Using Python 2.7.9 and lxml 2.3

Upvotes: 3

Views: 1867

Answers (1)

sneg
sneg

Reputation: 2216

It looks like getpath() (underlying libxml2 call xmlGetNodePath) produces positional expression xpath for namespaced documents. User mzjn in the comments section pointed out that since lxml v3.4.0 a function getelementpath() produces a human-readable xpath with fully qualified tag names (using "Clark notation"). This function generates xpath by traversing the tree from the node up to the root instead of using libxml2 API call.

Similarly, if lxml v3.4+ is not available one can write a tree traversal function of their own.

Upvotes: 3

Related Questions