Python: libxml2 xpath возвращает пустой список - PullRequest
0 голосов
/ 05 мая 2011

Я хочу проанализировать содержимое XML с помощью libxml2 Python, используя xpath, я следовал этому примеру и этому руководству . XML-файл:

<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://purl.org/atom/ns#" version="0.3">
<title>Gmail - Inbox for myemailaddress@gmail.com</title>
<tagline>New messages in your Gmail Inbox</tagline>
<fullcount>1</fullcount>
<link rel="alternate" href="http://mail.google.com/mail" type="text/html"/>
<modified>2011-05-04T18:56:19Z</modified>
</feed>

Этот XML хранится в файле с именем "atom", и я пробую следующее:

>>> import libxml2
>>> myfile = open('/pathtomyfile/atom', 'r').read()
>>> xmldata = libxml2.parseDoc('myfile')
>>> data.xpathEval('/fullcount')
[]
>>>

Теперь, как вы видите, он возвращает пустой список. Независимо от того, что я могу предоставить xpath, он вернет пустой список. Однако, если я использую подстановочный знак *, я получу список всех узлов:

>>>> data.xpathEval('//*')
[<xmlNode (feed) object at 0xb73862cc>, <xmlNode (title) object at 0xb738650c>, <xmlNode (tagline) object at 0xb73865ec>, <xmlNode (fullcount) object at 0xb738660c>, <xmlNode (link) object at 0xb738662c>, <xmlNode (modified) object at 0xb738664c>]

Теперь я не понимаю, судя по приведенным выше рабочим примерам, почему xpath не находит узел "fullcount" или любой другой: я использую тот же синтаксис в конце концов ...

Есть идеи или предложения? Спасибо.

Ответы [ 2 ]

2 голосов
/ 05 мая 2011

Ваш XPath не работает, потому что вам нужно указать purl namespace на узле:

import libxml2
tree = libxml2.parseDoc(data)
xp = tree.xpathNewContext()
xp.xpathRegisterNs("purl", "http://purl.org/atom/ns#")
print xp.xpathEval('//purl:fullcount')

Результат:

[<xmlNode (fullcount) object at 0x7fbbeba9ef80>]

(Также: проверитьlxml, имеет более качественный интерфейс более высокого уровня).

0 голосов
/ 05 мая 2011

Во-первых:

/fullcount - это абсолютный путь, поэтому он ищет элемент <fullcount> в корне документа, когда этот элемент фактически находится внутри <feed> element.

Во-вторых:

Вам необходимо указать пространство имен.Вот как вы это сделаете с lxml :

import lxml.etree as etree

tree = etree.parse('/pathtomyfile/atom')

fullcounts = tree.xpath('//ns:fullcount',
                namespaces={'ns': "http://purl.org/atom/ns#"})

print etree.tostring(fullcounts[0])

Что даст вам:

<fullcount xmlns="http://purl.org/atom/ns#">1</fullcount>
...