Python:libxml2 xpath返回空列表

时间:2011-05-04 22:18:18

标签: python list xpath libxml2

我想使用xpath解析Python的libxml2的XML内容,我跟着this examplethat tutorial。 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 个答案:

答案 0 :(得分:2)

您的XPath失败,因为您需要在节点上指定 purl命名空间

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,它有一个更好的,更高级别的接口)。

答案 1 :(得分:0)

<强>首先

/fullcount是一个绝对路径,因此当元素实际上位于<fullcount>元素内时,它正在文档根目录中查找<feed>元素。

<强>其次:

您需要指定命名空间。这是您使用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>
相关问题