XSLT - 我可以创建一个作为文档节点存储库的临时文档吗?

时间:2011-07-19 13:45:18

标签: xml xslt

假设我有以下临时文件:

<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中是否可行?

提前致谢。

3 个答案:

答案 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中,您可以使用“,”运算符代替“|”来定义节点序列,然后节点将按所需顺序排列。