[英]Xslt 1.0 apply-templates on a variable node-set changes root node
I have a xslt template and I was trying to segment all the logic for my items into different files and templates so everything would be nice and neat. 我有一个xslt模板,我试图将我的商品的所有逻辑都分割成不同的文件和模板,以便一切都很好。 I am using Microsofts xslt processor btw. 我正在使用Microsoft的xslt处理器。
Well, I ran into this problem where I call apply-template on a variable that is a node-set and the node-set becomes root xml node. 好吧,我遇到了一个问题,我在一个变量上调用了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 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 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>
Without Templates 没有模板
<!-- Works -->
<xsl:copy-of select="key('orderItemsByOrderId',key('ordersByUserId',loginID)/Id)"/>
EDIT: I have it set up in different files right now. 编辑:我现在将其设置在其他文件中。 I did take all of the files and copy paste them into the one xslt and this still happened. 我确实拿走了所有文件,然后将它们复制粘贴到一个xslt中,但这种情况仍然发生。
Now, If I undo the templates and just have a list of Key('',key('',key(''.....etc it will work because "/" contains everything still. But when I apply templates, this happens. 现在,如果我撤消模板,只拥有Key('',key('',key(''........)的列表,那么它将起作用,因为“ /”仍然包含所有内容。但是当我应用模板时,有时候是这样的。
I saw the question XSLT: Process an Xml node set in a template while still having access to the document root which is a way to get around it. 我看到了问题XSLT:处理模板中的Xml节点集,同时仍然可以访问文档根目录 ,这是解决它的一种方法。 But my question is more of a why does this even happen and how is it handled in XSLT 2.0? 但是我的问题更多是为什么会发生这种情况以及如何在XSLT 2.0中进行处理? (even though MS will never update to 2.0) (即使MS永远不会更新到2.0)
I thought that in XSLT 2.0 the result tree fragment was done away with. 我以为在XSLT 2.0中结果树片段已被删除。 Is there still a "Result Tree Fragment" like object, but it now supports "/" operations and such? 是否仍存在类似“结果树片段”的对象,但是它现在支持“ /”操作等? or is everything a node-set? 还是一切都是节点集?
The trouble is that the nodes in your _orders
variable aren't the original nodes from the input document but rather newly created copies of those nodes in a result tree fragment. 问题在于_orders
变量中的节点不是输入文档中的原始节点,而是结果树片段中这些节点的新创建副本 。 The msxsl:node-set
function turns this RTF into a single document root node (in XPath data model terms - in DOM terms it's a document fragment) with the copied tblPay_Orders
elements as its children. msxsl:node-set
函数将此RTF转换为一个单个文档根节点(以XPath数据模型的术语-以DOM术语来说,它是一个文档片段),并将复制的tblPay_Orders
元素作为其子元素。
So when you apply-templates
to these nodes you're changing the current document to this fragment, so /
then refers to the fragment node rather than the original document root (more precisely, a path of /
refers to the root node of whichever document the current context node belongs to), and the key
function looks up nodes in the fragment. 因此,当您apply-templates
应用于这些节点时,您会将当前文档更改为该片段,因此/
然后引用片段节点,而不是原始文档的根(更确切地说, /
的路径指的是任何文档的根节点当前上下文节点所属),并且key
函数在片段中查找节点。
You would have exactly the same issue in XSLT 2.0 if you used the same template (XSLT 2.0 calls it a "temporary tree" rather than a RTF but the principle is the same) - copy-of
still creates new nodes in a temporary tree. 如果使用相同的模板(XSLT 2.0称其为“临时树”而不是RTF,但原理相同),则在XSLT 2.0中将出现完全相同的问题- copy-of
仍会在临时树中创建新节点。 But you could use xsl:sequence
instead: 但是您可以改用xsl:sequence
:
<xsl:template match="tblLogins" mode="GetOrders" >
<xsl:sequence select="key('ordersByUserId',loginID)"/>
</xsl:template>
The difference here is that xsl:sequence
returns the original nodes attached to the original document rather than creating temporary copies in a new tree. 此处的区别在于xsl:sequence
返回附加到原始文档的原始节点,而不是在新树中创建临时副本。
Read about the <xsl:import>
and <xsl:include>
instructions. 阅读<xsl:import>
和<xsl:include>
指令。
http://www.w3.org/TR/1999/REC-xslt-19991116#import http://www.w3.org/TR/1999/REC-xslt-19991116#import
and: 和:
http://www.w3.org/TR/1999/REC-xslt-19991116#include http://www.w3.org/TR/1999/REC-xslt-19991116#include
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.