Python:libxml2 xpath 返回空列表

0 投票
2 回答
2153 浏览
提问于 2025-04-16 17:01

我想用Python的libxml2库通过xpath来解析XML内容。我参考了这个例子那个教程。我的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

首先:

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

撰写回答