Как получить xpathContext из xmlNode в python
Большой поклонник xpath в.net и sax в python, но впервые использовал xpath в python.
У меня есть небольшой скрипт, который использует xpath для выбора некоторых узлов в документе, выполняет итерацию по ним, а затем в идеале снова использует xpath для получения соответствующих данных из них. Однако я не могу получить этот последний бит, когда у меня есть xmlNode, я не могу получить контекст из него.
import libxml2
import urllib
doc = libxml2.parseDoc(
urllib.urlopen('http://somemagicwebservice.com/').read())
ctxt = doc.xpathNewContext()
listitems = ctxt.xpathEval('//List/ListItem')
for item in listitems:
itemctxt = item.xpathNewContext()
title = itemctxt.xpathEval('//ItemAttributes/Title')
asin = itemctxt.xpathEval('//Item/ASIN')
itemctxc.xpathFreeContext()
ctxt.xpathFreeContext()
doc.freeDoc()
Тем не менее itemctxt = item.xpathNewContext()
бит терпит неудачу с
itemctxt = item.xpathNewContext()
AttributeError: xmlNode instance has no attribute 'xpathNewContext'
Любые идеи, как использовать xpath на xmlNode? Я не могу найти хорошую информацию онлайн. Спасибо
2 ответа
Я не думаю, что XPathContext имеет смысл для элемента? Попробуйте создать новый XPathContext и установить для его узла текущий элемент.
Тем не менее, я не использовал libxml2 напрямую, так что это немного дикое предположение. Обычно я использую lxml, который предоставляет API ElementTree вокруг libxml2 и libxslt. Его гораздо проще использовать, и он действительно разрешает xpath() для элементов. Конечно, если у вас уже есть много кода, использующего libxml2, вы, вероятно, не хотите переключаться, но в этом случае вы можете взглянуть на исходный код lxmls, чтобы увидеть, как он это делает.
http://codespeak.net/svn/lxml/trunk/src/lxml/xpath.pxi
http://codespeak.net/svn/lxml/trunk/src/lxml/_elementpath.py
Кажется, хорошие стартовые места.
/questions/7607984/python-i-libxml2-kak-vyipolnyat-iteratsii-v-uzlah-xml-s-xpath/7607996#7607996 предлагает позвонить setContextNode(..)
на вновь созданном контексте:
itemctxt = doc.xpathNewContext()
for item in listitems:
itemctxt.setContextNode(item)
title = itemctxt.xpathEval('.//ItemAttributes/Title')
...
itemctxt.xpathFreeContext()
В версии Python libxml (2.9.1), которую я сейчас использую, оказывается, что можно даже вызвать:
item.xpathEval('.//ItemAttributes/Title')
Обратите внимание, что вам нужно добавить точку в начале выражений xpath .//
(вместо //
), иначе вы получите результаты поиска относительно корня документа.