2009-10-16 11 views
20

Je recherche dans un document HTML en utilisant XPath à partir de lxml en python. Comment puis-je obtenir le chemin vers un certain élément? Voici l'exemple de nokogiri rubis:Comment obtenir le chemin d'un élément dans lxml?

page.xpath('//text()').each do |textnode| 
    path = textnode.path 
    puts path 
end 

impression par exemple '/html/corps/div/div [1]/div [1]/p/text() [1]' et c'est la chaîne que je veux obtenir en python.

Répondre

38

Utilisez getpath à partir d'objets ElementTree.

from lxml import etree 

root = etree.fromstring('<foo><bar>Data</bar><bar><baz>data</baz>' 
         '<baz>data</baz></bar></foo>') 

tree = etree.ElementTree(root) 
for e in root.iter(): 
    print tree.getpath(e) 

Prints

/foo 
/foo/bar[1] 
/foo/bar[2] 
/foo/bar[2]/baz[1] 
/foo/bar[2]/baz[2] 
+0

Je pense qu'il devrait être 'pour e dans tree.iter():', c'est-à-dire ** tree **. Iter. – Jabba

+1

@Jabba Et pourquoi pensez-vous cela? Avez-vous essayé le code que j'ai fourni tel qu'il est? Cela semble fonctionner, non? Avez-vous une ** raison ** de penser autrement? – nosklo

+0

Il peut ne pas avoir existé lorsque vous avez écrit cela à l'origine et non pas que cela ait réellement de l'importance, mais vous pouvez aussi faire 'tree = root.getroottree()' pour obtenir un objet ElementTree. –

17

Voir la Xpath and XSLT with lxml from the lxml documentation Cela donne le chemin de l'élément containg le texte

Un exemple serait

import cStringIO 
from lxml import etree 

f = cStringIO.StringIO('<foo><bar><x1>hello</x1><x1>world</x1></bar></foo>') 
tree = lxml.etree.parse(f) 
find_text = etree.XPath("//text()") 

# and print out the required data 
print [tree.getpath(text.getparent()) for text in find_text(tree)] 

# answer I get is 
>>> ['/foo/bar/x1[1]', '/foo/bar/x1[2]'] 
3
root = etree.parse(open('tmp.txt')) 

for e in root.iter(): 
    print root.getpath(e) 
2

Si vous tous h ave dans votre section de code est l'élément et vous voulez faire xpath de l'élément alors element.getroottree().getpath(element) fera le travail.

from lxml import etree 

xml = ''' 
<test> 
    <a/> 
    <b> 
     <i/> 
     <ii/> 
    </b> 
</test> 
''' 
tree = etree.fromstring(xml) 

for element in tree.iter(): 
    print element.getroottree().getpath(element)