使用XPath,如何处理包含冒号字符的属性?

时间:2017-11-17 15:00:25

标签: python xml xpath lxml

给出以下XML(片段):

<node id="b071f9fa-14b0-4217-8e97-eb41da73f598" type="Group" ext:score="90">
<node id="b071f9fa-14b0-4217-8e97-eb41da73f599" type="Person" ext:score="100">
<node id="b071f9fa-14b0-4217-8e97-eb41da73f600" type="Business" ext:score="80">

我想检索id为100的ext:score个节点。

当前代码:

match = dom.xpath('//node[@ext:score="100"]/@id')[0]

返回一个异常:

lxml.etree.XPathEvalError: Undefined namespace prefix

我已经读过(在这里和XPath文档中)ext首先需要被定义为有效的命名空间,因为如果DOM包含 special 人物。但是,我一直无法找到如何做到这一点的好例子。我正在处理的摘录中没有ext的定义,我也不确定如何创建名称空间prefix

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

XML属性(或元素)名称中的冒号字符(例如ext:score)将名称空间前缀ext与本地名称score分开。命名空间前缀本身只有通过与命名空间值的关联才有意义。

对于此XML,

<metadata xmlns:ext="http://musicbrainz.org/ns/mmd-2.0#">
  <node id="b071f9fa-14b0-4217-8e97-eb41da73f598" type="Group" ext:score="90">
  <node id="b071f9fa-14b0-4217-8e97-eb41da73f599" type="Person" ext:score="100">
  <node id="b071f9fa-14b0-4217-8e97-eb41da73f600" type="Business" ext:score="80">
</metadata>

这个XPath,

//node[@ext:score="100"]/@id

将选择id属性值为node的所有ext:score元素的100属性,如果您有办法绑定命名空间前缀( ext)到调用XPath的语言或工具中的命名空间值(http://musicbrainz.org/ns/mmd-2.0#

在Python中将名称空间前缀绑定到名称空间值(有关Python和其他语言示例,请参阅How does XPath deal with XML namespaces?):

from lxml import etree
f = StringIO('your XML here')
doc = etree.parse(f)
r = doc.xpath('//node[@ext:score="100"]/@id', 
              namespaces={'ext':'http://musicbrainz.org/ns/ext#-2.0'})

请注意,如果您的XML使用ext而未声明,则不是namespace-well-formed.