Python 2.7 libxml2,XPath,提取xml属性

时间:2012-04-03 01:52:39

标签: python xpath libxml2

我有以下代码:

import libxml2
import sys

def xpath_grep(query, file):
    doc = libxml2.parseDoc(file)
    for matched_region in doc.xpathEval(query):
        matched_region.saveTo(sys.stdout, format = True) # add match to stdout

if __name__ == '__main__':
    if len(sys.argv) <= 1:
        # default arguments
        query = "data(bn/variable/@name)"
        files = ["burglary_bn.xml"]
    else:
        query = sys.argv[1]
        files = sys.argv[2:]

    for xml_file in files:
        xpath_grep(query, file(xml_file).read())

虽然我认为“data”函数应该检索XML属性的值,但事实并非如此。相反,它给了我一个错误:

xmlXPathCompOpEval: function data not found
Unregistered function
...
libxml2.xpathError: xmlXPathEval() failed

我做错了什么?

编辑:可以在此处找到XPath数据功能的文档: http://www.w3.org/TR/xpath-functions/#func-data

3 个答案:

答案 0 :(得分:1)

您不需要调用xpath函数来获取属性的值。例如,给定以下XML文档:

<doc>
  <section>
    <person name="bob" color="blue"/>
  </section>
</doc>

这个Python代码将获得name属性的值:

>>> doc = libxml2.parseDoc(open('input.xml').read())
>>> str(doc.xpathEval('//person/@name')[0].children)
'bob'

之前我从未使用过libxml2模块,因此可能有更好的方法。我总是使用lxml etree模块,使用它我们可以完成同样的事情:

>>> import lxml.etree as etree
>>> d = etree.parse(open('foo.xml'))
>>> d.xpath('//person/@name')[0]
'bob'

如果您可以使用它,ElementTree(etree)API更容易使用。

答案 1 :(得分:1)

data()是一个XPath 2.0函数,并未在XSLT 1.0处理器中实现,如libxml

您需要评估以下表达式:

bn/variable/@name

并迭代(在Python中)获取每个选定节点的字符串值。

答案 2 :(得分:0)

您没有定义函数data(),或者至少没有导入具有子模块名称数据的正确模块。 在您的代码中:

query = "data(bn/variable/@name)"

看起来很奇怪。为什么要调用这样的函数,如果数据函数可用,它究竟会做什么?