Python libxml2 XPath / Namespace Help - PullRequest
       2

Python libxml2 XPath / Namespace Help

3 голосов
/ 29 ноября 2010

Я пытаюсь узнать, как выполнять запросы XPath из Python, используя этот пример XML-файла: http://pastie.org/1333021 Я просто добавил к нему пространство имен, потому что мое реальное приложение использует его.

По сути,Я хочу выполнить запрос верхнего уровня, который возвращает подмножество узлов, а затем запросить подмножество (в гораздо большем масштабе, чем этот пример)

Так что это мой код, чтобы сначала найти все узлы <food>, а затемитерируем описание каждого из них.

#!/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

Так что, по сути, это проблема пространства имен, если я удаляю атрибут xlns из файла XML и использую только простые запросы XPATH без db:, он работает нормально.Верхний запрос //db:food работает нормально, но второй не дает оценки.

Пожалуйста, кто-нибудь может исправить мой синтаксис пространства имен / запроса.

Большое спасибо

1 Ответ

5 голосов
/ 29 ноября 2010

Я обычно не использую libxml2, я очень предпочитаю lxml.etree.

Поиграл.Метод xpathEval на вашем узле каждый раз создает новый контекст, очевидно, без зарегистрированного пространства имен.

Вы можете сбросить свой контекст в разные места, например:

>>> 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>
...