1

谁能向我解释为什么以下xslt:

<xsl:if test="EventDocument">

不拾取这个 xml 标签?

<EventDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.itron.com/ItronInternalXsd/1.0/">

当我从标签中删除属性时它会起作用,这对我来说毫无意义。

IE 当我将输入修改为时,上述测试通过:

<EventDocument>

我正在使用 xslt 2.0 (saxon parser) 在此先感谢

4

2 回答 2

2

默认情况下,XPath 表达式中不带前缀的元素名称是指没有命名空间的元素,因此表达式EventDocument选择具有本地名称“EventDocument”且没有命名空间的元素。这

<EventDocument ... xmlns="http://www.itron.com/ItronInternalXsd/1.0/">

元素与此模式不匹配,因为它在http://www.itron.com/ItronInternalXsd/1.0/命名空间中。

你有两个选择,要么

  1. 将该命名空间绑定到stylesheet 中的前缀,然后使用 XPath 表达式中的前缀,或者
  2. (因为你说你在 XSLT 2.0 中)使用xpath-default-namespace

示例 1

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:itron="http://www.itron.com/ItronInternalXsd/1.0/"
       version="2.0">

  <xsl:template match="itron:example">
    <xsl:if test="itron:EventDocument">....</xsl:if>
  </xsl:template>
</xsl:stylesheet>

示例 2

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xpath-default-namespace="http://www.itron.com/ItronInternalXsd/1.0/"
       version="2.0">

  <xsl:template match="example">
    <xsl:if test="EventDocument">....</xsl:if>
  </xsl:template>
</xsl:stylesheet>

我个人的偏好是选项 1,基于“最小意外原则”,任何人都必须在未来维护样式表(包括原作者,在休息几个月后回到代码......)。

于 2013-01-17T17:18:32.083 回答
2

xmlns是“保留属性” - 它是命名空间前缀到完整节点命名空间的映射定义。XML 中的“ xmlns ”是什么意思?

即,在您的情况下节点的实际名称是"http://www.itron.com/ItronInternalXsd/1.0/" EventDocument,但您尝试选择"" EventDocument(名称为“EventDocument”且名称空间为空的节点)。

根据您需要的 XPath 引擎

  • 将命名空间前缀的映射传递给命名空间
  • 对命名空间和节点名称使用显式匹配。*[namespace-uri()="http://www.itron.com/ItronInternalXsd/1.0/" and local-name()=="EventDocument"]
  • 作弊,只匹配节点名称*[local-name()=="EventDocument"]

local-namenamespace-urihttp://www.w3.org/TR/xpath/#section-Node-Set-Functions中介绍)。

于 2013-01-17T17:06:09.627 回答