2013-08-30 43 views
1

我有一个xslt模板,我试图将我的项目的所有逻辑分割成不同的文件和模板,所以一切都会很好,很整齐。我使用微软xslt处理器btw。Xslt 1.0在变量节点集上应用模板更改根节点

嗯,我遇到了这个问题,我调用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中,但这仍然发生。现在,如果我撤消模板,只是有一个键列表('',键('',键(''.....等),它将工作,因为“/”包含所有东西,但是当我应用模板,发生这种情况

我看到了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结果树片段已被废除。是否仍然有一个“结果树片段”像对象,但它现在支持“/”操作等?所有节点集?

回答

1

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

所以,当你apply-templates到这些节点你改变当前文档这一片段,所以/则是指该片段节点而不是原来的文档根目录(更准确地说,是的/路径指的根节点无论当前上下文节点属于哪个文档),并且key函数在片段中查找节点。

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

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

的此不同的是,xsl:sequence返回附加到原始文档,而不是在一个新的树创建临时复制原始节点。

+0

Arg。这是有道理的,但它仍然很糟糕,我不能按我想要的方式组织它。 – Buttink