【问题标题】:Xslt 1.0 apply-templates on a variable node-set changes root node变量节点集上的 Xslt 1.0 应用模板更改根节点
【发布时间】:2013-08-30 20:19:12
【问题描述】:

我有一个 xslt 模板,我试图将我的项目的所有逻辑分段到不同的文件和模板中,这样一切都会很好而且整洁。顺便说一句,我正在使用 Microsoft 的 xslt 处理器。

好吧,我遇到了这个问题,我在一个节点集的变量上调用 apply-template 并且节点集成为根 xml 节点。

<xsl:import href="tblLogins.xslt"/>
<xsl:import href="tblPay_OrderItems.xslt/>



            <xsl:variable name="item" select="/Entities/Data/tblLogins"/>
            <!-- Get the users orders -->
            <xsl:variable name="_orders" >
                <xsl:apply-templates select="$item" mode="GetOrders" />
            </xsl:variable>
            <xsl:variable name="orders" select="msxsl:node-set($_orders)/*" />
            <!-- Get the order's items -->
            <!-- This works and we now have all the orders -->
            <xsl:variable name="_orderItems" >
                <xsl:apply-templates select="$orders" mode="GetOrderItems" />
            </xsl:variable>
            <xsl:variable name="orderItems" select="msxsl:node-set($_orderItems)/*" />
            <!-- will always be empty -->

tblLogins.xslt

<xsl:key name="ordersByUserId" match="tblPay_Orders" use="UserId" />

<xsl:template match="tblLogins" mode="GetOrders" >
    <xsl:copy-of select="key('ordersByUserId',loginID)"/>
</xsl:template>

tblPay_Order.xslt

<xsl:key name="orderItemsByOrderId" match="tblPay_OrderItems" use="OrderId" />

<xsl:template match="tblPay_Orders" mode="GetOrderItems" >
    <!-- "/" is now the tblPay_Orders and nothing else is available -->
    <xsl:copy-of select="key('orderItemsByOrderId',Id)"/>
    <!-- will return nothing -->
</xsl:template>

没有模板

<!-- Works -->
<xsl:copy-of select="key('orderItemsByOrderId',key('ordersByUserId',loginID)/Id)"/>

编辑:我现在将它设置在不同的文件中。我确实拿走了所有文件并将它们复制粘贴到一个 xslt 中,但仍然发生了这种情况。

现在,如果我撤消模板并且只有一个 Key('',key('',key(''.....etc 的列表它将起作用,因为“/”仍然包含所有内容。但是当我应用模板,就会发生这种情况。

我看到了XSLT: Process an Xml node set in a template while still having access to the document root 的问题,这是一种绕过它的方法。但我的问题更多的是为什么会发生这种情况以及它在 XSLT 2.0 中是如何处理的? (尽管 MS 永远不会更新到 2.0)

我认为在 XSLT 2.0 中,结果树片段被取消了。是否还有类似对象的“结果树片段”,但它现在支持“/”操作等?还是一切都是节点集?

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    问题在于_orders 变量中的节点不是输入文档中的原始节点,而是结果树片段中这些节点的新创建副本msxsl:node-set 函数将此 RTF 转换为单个文档根节点(在 XPath 数据模型术语中 - 在 DOM 术语中它是文档片段),其中复制的 tblPay_Orders 元素作为其子元素。

    所以当您apply-templates 到这些节点时,您正在将当前文档更改为该片段,因此/ 指的是片段节点而不是原始文档根(更准确地说,/ 的路径指到当前上下文节点所属的文档的根节点),key 函数在片段中查找节点。

    如果您使用相同的模板,您将在 XSLT 2.0 中遇到完全相同的问题(XSLT 2.0 将其称为“临时树”而不是 RTF,但原理相同)-copy-of 仍然在临时树。但你可以改用xsl:sequence

    <xsl:template match="tblLogins" mode="GetOrders" >
        <xsl:sequence select="key('ordersByUserId',loginID)"/>
    </xsl:template>
    

    这里的区别在于xsl:sequence 返回附加到原始文档的原始节点,而不是在新树中创建临时副本。

    【讨论】:

    • 精氨酸。这是有道理的,但是我不能真正按照我想要的方式组织它,这仍然很糟糕。
    【解决方案2】:

    阅读&lt;xsl:import&gt;&lt;xsl:include&gt; 说明。

    http://www.w3.org/TR/1999/REC-xslt-19991116#import

    和:

    http://www.w3.org/TR/1999/REC-xslt-19991116#include

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      相关资源
      最近更新 更多