Xslt 构造而不是选择XSL节点集变量
我希望使用包含的for each循环构造一个XSL节点集变量。重要的是,构造的节点集是原始(选定)节点集,而不是副本 这是我的问题的一个简化版本(当然可以通过选择来解决,但这不是问题的重点)。我使用这个节点来测试构造的节点集变量实际上在原始树中,而不是副本 XSL版本1.0,处理器为msxsl 非工作XSL:Xslt 构造而不是选择XSL节点集变量,xslt,xslt-1.0,msxsl,Xslt,Xslt 1.0,Msxsl,我希望使用包含的for each循环构造一个XSL节点集变量。重要的是,构造的节点集是原始(选定)节点集,而不是副本 这是我的问题的一个简化版本(当然可以通过选择来解决,但这不是问题的重点)。我使用这个节点来测试构造的节点集变量实际上在原始树中,而不是副本 XSL版本1.0,处理器为msxsl 非工作XSL: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1" omit-xml-declaration="yes" />
<xsl:template match="/">
<xsl:variable name="entries">
<xsl:for-each select="//entry">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="entryNodes" select="msxsl:node-set($entries)"/>
<xsl:for-each select="$entryNodes">
<xsl:value-of select="/root/name"/>
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
实际产量:
12
当然(或a)的问题是复制的,但我想不出解决的办法
我希望使用包含的
对于每个循环
我不知道那是什么意思
构造的节点集必须是原始的(a
选中)节点集,而不是副本
这一部分我想我理解得好一点。似乎您需要更换:
<xsl:variable name="entries">
<xsl:for-each select="//entry">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
以获得您预期的结果
当然,您也可以通过在原始节点的原始上下文中直接对其进行操作来完成相同的任务,而不需要变量
回应您的评论: 我们显然需要一个更好的例子,但我想我对你想做的事情有一个模糊的概念。但有几件事你必须先了解: 1.
为了构造包含原始上下文中节点的节点集的变量,必须使用
select
。这不会对您的选择设置任何限制。您可以一次完成所有选择,也可以分阶段完成,甚至可以在循环中完成选择(这里我指的是真正的循环)。可以以任何方式组合集合,包括并集、交集或差集,来组合所做的中间选择。但是您必须在所有这些步骤中使用select
,否则您将得到一组新节点,不再具有它们在源树中的上下文
照此,使用copy
和select
的唯一区别在于前者创建新节点,这正是您希望避免的
2.xsl:for-each
不是一个循环。它没有层次结构或年表。所有节点都是并行处理的,并且没有办法在当前节点中使用上一次迭代的结果,因为没有迭代是“上一次”的
如果尝试使用xsl:for each
将n个处理过的节点中的每一个添加到预先存在的节点集中,最终将得到n个结果,每个结果都包含与其中一个处理过的节点连接的预先存在的节点集
3.我认为您会发现XPath语言非常强大,它允许您选择所需的节点,而不必经过您提示的复杂循环 XSLT1.0中没有“绕过它的方法”——这正是应该如何工作的。如果变量是用内容而不是用
select
声明的,则该内容是由新创建的节点组成的结果树片段(即使这些节点是原始树中节点的副本)。如果要引用附加到原始树的原始节点,则必须使用select
声明变量。一个更好的问题是详细说明实际问题,并询问如何编写合适的select
表达式来查找所需的节点,而无需为每个使用——大多数xsl:if
或xsl:choose
的用法都可以用适当构造的谓词替换,可能需要明智地使用xsl:key
,等等
在XSLT2.0中,它更加灵活。节点集和结果树片段之间没有区别,xsl:variable
的内容被视为通用的“序列构造函数”,如果您构造或复制它们,它可以为您提供新节点:
<xsl:variable name="example" as="node()*">
<xsl:copy-of select="//entry" />
</xsl:variable>
如果您向我们展示了一个在XSLT1.0中无法简单解决的问题,这可能会有所帮助。您不能按要求的方式解决问题:XSLT1.0中没有与xsl:sequence等价的东西。但是你向我们展示的问题可以不用这样的构造来解决。所以,请解释一下你为什么需要你想要的东西。嗨,迈克尔。对不起,如果我的措辞令人困惑,也许我太简短了。我的意思是,“我希望构造一个包含节点集的XSL变量,在变量元素中使用for-each循环,而不是使用select属性。”如后所述,“当然可以用select解决,但这不是问题的重点”。这里的解决方案使用select属性。很抱歉,问题不清楚。或者“我希望构造一个包含节点集的XSL变量,在变量定义节点的内容中使用for-each循环,而不是通过使用其select属性,而是具有与使用select属性相同的效果。”我希望这里的术语更准确。@CaptainNormal根据你对这个和其他答案的评论,我在我的答案中添加了一些注释;他们太长了,无法发表评论。我会看看是否能想出一个与我真正的问题类似的例子。我真正的问题涉及一个“复杂”的算法,它涉及命名模板调用来构造一个包含节点集的变量,并将该变量传递给其他几个模板,在链的末尾,我需要在XML的一个完全不相关的部分中找到一个元素,并将其与另一个XML文件中的一个相关元素进行比较。如果我能将select放入循环中,您的项目#1可能会起作用。这个例子将与这个问题完全无关,因此我将单独发布它;我会在这里贴一个链接。@CaptainNormal请记住还有其他可能的方法。例如,不收集其原点中的实际节点
<xsl:variable name="entries">
<xsl:for-each select="//entry">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="entries" select="//entry"/>
<xsl:variable name="entries" select="root/entry"/>
<xsl:for-each select="$entries">
<xsl:value-of select="/root/name"/>
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:variable name="example" as="node()*">
<xsl:copy-of select="//entry" />
</xsl:variable>
<xsl:variable name="example" as="node()*">
<xsl:sequence select="//entry" />
</xsl:variable>