1

在 xslt-stylesheet 中,我使用方法exsl:node-setset:distinct从包含结果树片段的变量中访问和过滤唯一节点。我可以将这些节点的值写入我的输出文件,例如:

<xsl:variable name="myNodes">
  <xsl:call-template name="getNodes"/>
</xsl:variable>

<xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
  <xsl:value-of select="."/>
</xsl:for-each>

正如预期的那样,键的值被写入输出。但是,如果我尝试使用 XPath 表达式中的值,它会失败:

<xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
  <xsl:variable name="result" select="/tree//somenode[@key = current()]"/>
  <xsl:value-of select="$result"/>
</xsl:for-each>

现在,输出是空的,而我知道我的 input-xml 中有一个“somenode”应该由 XPath 表达式选择,并且它的值不为空。

现在我的问题是:为什么会发生这种情况?

我正在使用 Java 1.6、Xerces 2.7 和 Xalan 2.7。

更新:根据要求,示例的一些数据:xml doc 包含:

<tree>
  <somenode key="123"/>
  <num>123</num>
  <num>0815</num>
</tree>

getNodes 模板:

<xsl:template name="getNodes">
  <xsl:for-each select="/tree/num">
    <xsl:element name="key">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
</xsl:template>
4

2 回答 2

3

这是一个转换,它做的事情接近你想要的

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:set="http://exslt.org/sets"
 xmlns:exsl="http://exslt.org/common"
 >
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="/">
  <xsl:variable name="myNodes">
    <xsl:call-template name="getNodes"/>
  </xsl:variable>


  <xsl:variable name="vDoc" select="/"/>

  <xsl:for-each select="set:distinct(exsl:node-set($myNodes)/key)">
    <xsl:variable name="result" select="$vDoc/tree//somenode[@key = current()]"/>
    <xsl:copy-of select="$result"/>
  </xsl:for-each>
 </xsl:template>

 <xsl:template name="getNodes">
  <xsl:for-each select="/tree/num">
    <xsl:element name="key">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<tree>
  <somenode key="123"/>
  <num>123</num>
  <num>0815</num>
</tree>

产生了想要的结果

<somenode key="123"/>

请注意

  1. 源 XML 文档不能直接在内部访问<xsl:for-each>因为该指令将当前节点设置为另一个文档中的节点 - 由exsl:node-set().

  2. 为此,我们在一个变量中捕获源 XML 文档$vDoc<xsl:for-each>我们通过这个变量访问内部的源 XML 文档。

  3. 该元素<somenode key="123"/>没有文本节点后代,因此没有字符串 value。使用<xsl:value-of>它不会产生任何输出。这就是我们<xsl:copy-of>在这里使用的原因——它复制了完整的元素并且我们看到了结果。

于 2010-08-26T12:51:36.997 回答
0

此样式表在没有扩展的情况下执行您想要的相同操作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="NumByValue" match="num" use="."/>
    <xsl:template match="num[count(.|key('NumByValue',.)[1])=1]">
        <xsl:copy-of select="../somenode[@key=current()]"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<somenode key="123" />
于 2010-08-26T13:22:33.537 回答