假设我有以下临时文件:
<xsl:variable name="emc">
<people>
<person id="1">
<name>Jim</name>
</person>
<person id="2">
<name>Joe</name>
</person>
</people>
</xsl:variable>
<xsl:variable name="ibm">
<people>
<person id="1">
<name>Joan</name>
</person>
<person id="2">
<name>Allison</name>
</person>
</people>
</xsl:variable>
我想要另一个文档来存储以前文档的根节点:
<xsl:variable name="store">
<store>
<doc>{$emc goes here}</doc>
<doc>{$ibm does here}</doc>
</store>
</xsl:variable>
我可以这样做,但我不能再使用doc元素的内容,因为我可以使用$ emc或$ ibm的值。
那样,
<xsl:variable name="doc1" select="$store/store/doc[1]">
并且$ doc1 / people / person [1]与$ ibm / people / person [1]
相同的节点这在某些版本的XSLT中是否可行?
提前致谢。
答案 0 :(得分:2)
查看特定于XSLT引擎的node-set
函数。例如,MSXML具有node-set()
功能,可将树转换为节点集。 http://msdn.microsoft.com/en-us/library/ms256197.aspx
答案 1 :(得分:2)
这里发生的是,在XSLT 1.0中,变量指令中的文字XML内容的值是'result tree fragment'(RTF),遗憾的是它不能直接作为节点集处理(除了将其视为具有字符串值的单个节点)。因此,使用/
或[]
的XPath表达式将无效。
解决方案是使用像node-set()
这样的extension function,正如@polishchuk所说的那样(但是让便携式变得更加棘手);或者使用XSLT 2.0。
在XSLT 2.0中,RTF data type is eliminated(并且非常高兴!)。变量的值是一个临时树,可以像源代码树一样由XPath运算符操作。
更新:保留节点标识
当您说“在商店文档中”(下面的评论)时,您的意思是在临时树中$store
变量的值?由于你在问题中有结构,所以这是不可能的,因为一些XML节点必须有两个父节点。但是,您可以将$store
树设为数据的实际位置,并从中选择$emc
和$ibm
:
<xsl:variable name="store">
<store>
<doc id="emc">
<people>
<person id="1">
<name>Jim</name>
</person>...
</people>
</doc>
<doc id="ibm">
<people>
<person id="1">
<name>Joan</name>
</person>...
</people>
</doc>
</store>
</xsl:variable>
<xsl:variable name="emc" select="$store/store/doc[@id='emc']" />
<xsl:variable name="ibm" select="$store/store/doc[@id='ibm']" />
然后$doc1/people/person[1]
与$ibm/people/person[1]
是同一个节点。
可以想象使用doc()
和外部文件的一些变体,但在花时间之前我想要了解更多关于您的要求,特别是上述场景如何不符合它们。
答案 2 :(得分:2)
存储一组文档节点所需的数据结构不是文档,而是节点集。所以不要这样:
<xsl:variable name="store">
<store>
<doc>{$emc goes here}</doc>
<doc>{$ibm does here}</doc>
</store>
</xsl:variable>
这样做:
<xsl:variable name="store" select="$emc | $ibm"/>
在XSLT 1.0中,这严格来说是一个节点集,因此您无法控制排序。在XSLT 2.0中,您可以使用“,”运算符代替“|”来定义节点序列,然后节点将按所需顺序排列。