2010-11-29 6 views
3

J'essaie d'apprendre comment faire des requêtes XPath à partir de Python en utilisant cet exemple de fichier XML: http://pastie.org/1333021 Je viens de lui ajouter un espace de nommage parce que mon application l'utilise.Python libxml2 XPath/Namespace Help

Fondamentalement, je veux exécuter une requête de niveau supérieur qui retourne un sous-ensemble de nœuds, puis interroger le sous-ensemble (sur une échelle beaucoup plus grande que cet exemple)

Donc, voici mon code pour d'abord trouver tous <food> nœuds puis itérer sur la description de chacun.

#!/usr/bin/python2 

import libxml2 

doc = libxml2.parseFile("simple.xml") 
context = doc.xpathNewContext() 

context.xpathRegisterNs("db", "http://examplenamespace.com") 
res = context.xpathEval("//db:food") 

for node in res: 
    # Query xmlNode here 
    print "Got Food Node:" 
    desc = node.xpathEval('db:description') # this is wrong? 
    print desc 

Il est donc essentiellement un problème d'espace de noms, si je retire l'attribut xlns à partir du fichier XML et utiliser des requêtes XPATH juste base sans db: il fonctionne très bien. La première requête //db:food fonctionne très bien, mais la seconde échoue à l'évaluation.

S'il vous plaît quelqu'un peut corriger ma syntaxe de l'espace de noms/requête.

Merci beaucoup

Répondre

5

Je ne l'utilise pas normalement libxml2, je préfère beaucoup lxml.etree.

Avait un jeu autour. La méthode xpathEval sur votre nœud crée un nouveau contexte à chaque fois, apparemment sans l'espace de noms que vous avez enregistré.

Vous pouvez réinitialiser votre contexte à différents endroits comme celui-ci:

>>> import libxml2 
>>> from urllib2 import urlopen 
>>> data = urlopen('http://pastie.org/pastes/1333021/download').read() 
>>> 
>>> doc = libxml2.parseMemory(data,len(data)) 
>>> 
>>> context = doc.xpathNewContext() 
>>> context.xpathRegisterNs("db", "http://examplenamespace.com") 
0 
>>> 
>>> for res in context.xpathEval("//db:food"): 
...  context.setContextNode(res) 
...  print "Got Food Node:" 
...  desc = context.xpathEval('./db:description')[0] 
...  print desc 
... 
Got Food Node: 
<description>two of our famous Belgian Waffles with plenty of real maple syrup</description> 
Got Food Node: 
<description>light Belgian waffles covered with strawberries and whipped cream</description> 
Got Food Node: 
<description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description> 
Got Food Node: 
<description>thick slices made from our homemade sourdough bread</description> 
Got Food Node: 
<description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description> 
+0

Merci beaucoup, je pense que je ne comprenais pas le contexte change :) – Jason