繁体   English   中英

为什么不能在XPath-Expression中使用通过exsl:node-set / set:distinct检索的节点的值?

[英]Why can't I use values of nodes I retrieve by using exsl:node-set/set:distinct in an XPath-Expression?

在xslt样式表中,我使用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中应该由XPath表达式选择一个“ somenode”,并且其值也不为空。

现在我的问题是:为什么会这样?

我正在使用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>

这是一个转换,可以完成您所需的操作

<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. 不能在<xsl:for-each>内部直接访问源XML文档,因为此指令将当前节点设置为另一个文档中的节点-由exsl:node-set()创建的临时树。

  2. 因此,我们将源XML文档捕获到变量$vDoc 我们通过此变量访问<xsl:for-each>内部的源XML文档。

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

此样式表无需扩展即可实现您想要的效果:

<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" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM