[英]Why can't I use values of nodes I retrieve by using exsl:node-set/set:distinct in an XPath-Expression?
In a xslt-stylesheet I'm using the methods exsl:node-set
and set:distinct
to access and filter unique nodes from a variable that contains a result tree fragment. 在xslt样式表中,我使用
exsl:node-set
和set:distinct
来访问和过滤包含结果树片段的变量中的唯一节点。 I can write the values of these nodes into my output file, example: 我可以将这些节点的值写入输出文件,例如:
<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>
The values of the keys are written in the output, just as expected. 按键值将按预期方式写入输出中。 However, if I try to use the values in an XPath expression, it fails:
但是,如果我尝试在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>
Now, the output is empty, whereas I know that there is a "somenode" in my input-xml that should be selected by the XPath expression and it's value is not empty. 现在,输出为空,而我知道在input-xml中应该由XPath表达式选择一个“ somenode”,并且其值也不为空。
Now my question is: Why does this happen? 现在我的问题是:为什么会这样?
I'm using Java 1.6, Xerces 2.7 and Xalan 2.7. 我正在使用Java 1.6,Xerces 2.7和Xalan 2.7。
update: as requested, some data for the example: xml doc contains: 更新:根据要求,示例的一些数据:xml doc包含:
<tree>
<somenode key="123"/>
<num>123</num>
<num>0815</num>
</tree>
the getNodes template: 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>
Here is a transformation that does something close to what you want : 这是一个转换,可以完成您所需的操作 :
<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>
when applied on the provided XML document : 当应用于提供的XML文档时 :
<tree>
<somenode key="123"/>
<num>123</num>
<num>0815</num>
</tree>
the wanted result is produced : 产生想要的结果 :
<somenode key="123"/>
Do note : 注意事项 :
The source XML document cannot direstly be accessed inside the <xsl:for-each>
, because this instruction sets the current node to a node in another document -- the temporary tree created by exsl:node-set()
. 不能在
<xsl:for-each>
内部直接访问源XML文档,因为此指令将当前节点设置为另一个文档中的节点-由exsl:node-set()
创建的临时树。
For this reason we capture the source XML document in a variable $vDoc
. 因此,我们将源XML文档捕获到变量
$vDoc
。 We access the source XML document inside the <xsl:for-each>
via this variable. 我们通过此变量访问
<xsl:for-each>
内部的源XML文档。
The element <somenode key="123"/>
has no text-node descendents and hence no string value . 元素
<somenode key="123"/>
没有文本节点后代,因此没有字符串值 。 Using <xsl:value-of>
on it will not produce any output. 在其上使用
<xsl:value-of>
不会产生任何输出。 This is why we use <xsl:copy-of>
here -- it copies the complete element and we see the result. 这就是为什么我们在这里使用
<xsl:copy-of>
-它复制了完整的元素,我们看到了结果。
This stylesheet does the same you want without extensions: 此样式表无需扩展即可实现您想要的效果:
<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>
Output: 输出:
<somenode key="123" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.