我希望使用包含的for-each循环构造一个XSL节点集变量。重要的是构造的节点集是原始(选定的)节点集,而不是副本。
这是我的问题的一个简化版本(当然可以通过选择解决,但这不是问题的重点)。我使用了< name>用于测试构造的节点集变量实际上是在原始树中而不是副本的节点。
XSL 1.0版,处理器是msxsl。
非工作XSL:
<?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>
XML输入:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>X</name>
<entry>1</entry>
<entry>2</entry>
</root>
通缉输出:
X1X2
实际输出:
12
当然(或者)问题是副本,但是我无法解决这个问题。
答案 0 :(得分:1)
我希望使用contains来构造一个XSL节点集变量 for-each loop。
我不知道这意味着什么。
构造的节点集是原始的(a 选择)节点集,而不是副本。
这部分我认为我明白了一点。看来你需要更换:
<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"/>
结果变量是原始entry
节点的节点集,因此您只需执行以下操作:
<xsl:for-each select="$entries">
<xsl:value-of select="/root/name"/>
<xsl:value-of select="."/>
</xsl:for-each>
获得预期结果。
当然,您可以通过在原始节点上直接操作原始上下文来执行相同的操作 - 无需变量。
回应您的评论:
我们显然需要一个更好的例子,但我想我对你想要去哪里有一个模糊的想法。但是你必须先了解一些事情:
<强> 1 强>
为了构造一个在原始上下文中包含节点的节点集的变量,必须使用select
。这对您可以选择的内容没有任何限制。你可以一次完成所有选择,也可以分阶段进行选择,甚至可以循环进行选择(这里我指的是一个真正的循环)。您可以组合您以任何方式组合的中间选择组合:联合,交集或差异。但是你必须在所有这些步骤中使用select
,否则你将得到一组新节点,不再具有他们在源树中所做的上下文。
IOW,使用copy
和select
之间的唯一区别是前者创建新节点,这正是您希望避免的。
<强> 2 强>
xsl:for-each
不是循环。它没有层次结构或年表。所有节点都是并行处理的,并且没有办法在当前节点中使用先前迭代的结果 - 因为没有迭代是&#34;之前的&#34;到另一个。
如果您尝试使用xsl:for-each
将每个已处理的节点添加到预先存在的节点集中,您将得到n个结果,每个结果包含已连接的预先存在的节点集一个已处理的节点。
第3 强>
我认为您会发现XPath语言非常强大,并且允许您选择所需的节点,而无需经历您提示的复杂循环。
答案 1 :(得分:1)
在XSLT 1.0中没有一种“解决方法” - 这正是它应该如何工作的。如果您有一个使用内容而不是select
声明的变量,则该内容是由新创建的节点组成的结果树片段(即使这些节点是原始树中节点的副本)。如果要引用附加到原始树的原始节点,则必须使用select
声明变量。更好的问题是详细说明实际问题并询问如何编写合适的select
表达式来查找所需的节点而无需使用for-each
- xsl:if
或{的大多数用法{1}}可以用适当构造的谓词替换,可能涉及明智地使用xsl:choose
等。
在XSLT 2.0中,它更加灵活。节点集和结果树片段之间没有区别,xsl:key
的内容被视为通用的“序列构造函数”,如果您构造或复制它们,它们可以为您提供新节点:
xsl:variable
或原始节点(如果您使用<xsl:variable name="example" as="node()*">
<xsl:copy-of select="//entry" />
</xsl:variable>
:
xsl:sequence
答案 2 :(得分:0)
如果您向我们展示了一个在XSLT 1.0中无法轻易解决的问题,这可能会有所帮助。您无法按照要求的方式解决问题:在XSLT 1.0中没有等效的xsl:sequence。但是,如果没有这样的结构,你可以解决你向我们展示的问题。所以请解释为什么你需要你想要的东西。