2010-11-29 79 views
3

我在学习如何使用这个示例XML文件从Python进行XPath查询:http://pastie.org/1333021我刚刚为它添加了一个名称空间,因为我的实际应用程序使用它。Python libxml2 XPath /命名空间帮助

基本上,我想执行一个顶级查询,返回节点的子集,然后查询的子集(上一个比这个例子更大的规模)

所以这是我的代码,首先找到所有<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 

所以它本质上是一个命名空间的问题,如果我请从XML文件中的xlns属性和使用无db:它工作正常,只是基本的XPath查询。顶部查询//db:food工作正常,但第二个查询失败。

请有人可以纠正我的命名空间/查询语法。

非常感谢

回答

5

我通常不使用的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> 
+0

非常感谢,我想我被搞糊涂了对环境的变化:) – Jason 2010-11-29 19:31:02