【问题标题】:Using XPath, how are attributes that contain a colon character processed?使用 XPath,如何处理包含冒号字符的属性?
【发布时间】:2018-05-01 09:40:15
【问题描述】:

给定以下 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">

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

当前代码:

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

返回异常:

lxml.etree.XPathEvalError: Undefined namespace prefix

我已阅读(此处和 XPath 文档中)ext 首先需要定义为有效的命名空间,因为如果 DOM 包含 特殊 字符,则无法将其解析为属性.但是,我一直找不到一个很好的例子来说明如何做到这一点。我正在处理的摘录中没有ext 的定义,我不确定如何创建命名空间prefix

有什么想法吗?

【问题讨论】:

  • 我已经阅读了@kjhughes,并且我了解如何创建 命名空间,但我不知道如何使用该命名空间前缀来测试健康)状况。还在寻找...谢谢!
  • 您的 XML 是否有 ext 的命名空间声明——类似于 xmlns:ext="http://example.com/extention"node 元素上方的元素上?
  • @kjhughes - 我没有(这些来找我原样,)但有人告诉我原件包含这个:&lt;metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0" created="2017-11-16T12:09:30.334Z"&gt; 这是什么我曾经尝试synthesize前缀。

标签: python xml xpath lxml


【解决方案1】:

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

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

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

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.

【讨论】:

  • 现在完美运行 - 非常感谢@kjhughes
猜你喜欢
  • 2021-08-28
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
相关资源
最近更新 更多