14

我得到了以下 XML:

<root>
  <items>
    <item>
      <title>Item</title>
      <details>
        <data xmlns="http://some_url">
          <length>10</length>
          <weight>1.2</weight>
        </data>
      </details>
    </item>
  </items>
</root>

遵循 XPath 不起作用,这意味着不会像“数据”元素那样打印任何内容:

/root/items/item/details/data

但是当我删除“数据”元素的“xmlns”命名空间属性时,它的内容就会被打印出来。在不删除“data”元素的“xmlns”命名空间属性的情况下,xpath 表达式应该如何工作?

我正在使用 SAXON 和 XSL 1.0。

4

2 回答 2

16

这是 XPath / XSLT 中最常见的问题之一

XPath 将不带前缀的元素名称解释为属于“无命名空间”,这就是在 XPath 表达式中仅将其不带前缀的名称指定为节点测试时,不选择属于默认(非空)命名空间的不带前缀名称的元素的原因.

解决方案是

  1. 创建一个命名空间绑定,其中前缀(比如"x")与默认命名空间相关联,然后指定x:elementName而不是elementName.

  2. 使用冗长、丑陋和不可靠的表达方式,例如:*[name() = 'elementName']

这是使用上述方法 1 进行的 XSLT 转换。:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:a="http://some_url">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:value-of select=
  "/root/items/item/details/a:data/a:weight"/>
 </xsl:template>
</xsl:stylesheet>

在提供的 XML 文档上应用此转换时(使用 Saxon 6.5.4 或任何其他兼容的 XSLT 1.0 处理器)

<root>
    <items>
        <item>
            <title>Item</title>
            <details>
                <data xmlns="http://some_url">
                    <length>10</length>
                    <weight>1.2</weight>
                </data>
            </details>
        </item>
    </items>
</root>

选择正确/想要的节点并将其字符串值复制到输出

1.2
于 2012-06-12T03:40:41.887 回答
0

在 XPath 中,您必须为命名空间分配一个前缀。如何执行此操作取决于您使用的 XPath 软件/库,但假设您将命名空间 URIhttp://some_url与命名空间前缀相关联someUrl,您可以更改 XPath 表达式,如下所示:

/root/items/item/details/someUrl:data
于 2012-06-11T13:47:30.360 回答