构建而不是选择 XSL 节点集变量 [英] Constructing, not selecting, XSL node set variable
问题描述
我希望使用包含的 for-each 循环构造一个 XSL 节点集变量.重要的是,构建的节点集是原始(选定的)节点集,而不是副本.
这是我的问题的简化版本(当然可以通过选择解决,但这不是问题的重点).我使用了 <name>node 来测试构造的节点集变量实际上是在原始树中而不是副本中.
XSL 版本 1.0,处理器为 msxsl.
非工作 XSL:
XML 输入:
<姓名>X</姓名><entry>1</entry><entry>2</entry></root>
想要的输出:
X1X2
实际输出:
12
当然,(或 a)问题是副本,但我无法解决这个问题.
在 XSLT 1.0 中没有解决方法" - 这正是它应该如何工作的.当您有一个用内容而不是用 select
声明的变量时,该内容是由新创建的节点组成的结果树片段(即使这些节点是原始树中节点的副本).如果要引用附加到原始树的原始节点,则必须使用 select
声明变量.更好的问题是详细说明实际问题,并询问如何编写合适的 select
表达式来查找所需的节点,而无需使用 for-each
- 大多数用途xsl:if
或 xsl:choose
可以替换为适当构造的谓词,可能涉及对 xsl:key
等的明智使用.><小时>
在 XSLT 2.0 中,它更加灵活.节点集和结果树片段之间没有区别,并且 xsl:variable
的内容被视为通用的序列构造函数",如果您构造或复制它们,它可以为您提供新节点:>
<xsl:copy-of select="//entry"/></xsl:变量>
或原始节点,如果您使用 xsl:sequence
:
<xsl:sequence select="//entry"/></xsl:变量>
I wish to construct an XSL node set variable using a contained for-each loop. It is important that the constructed node set is the original (a selected) node set, not a copy.
Here is a much simplified version of my problem (which could of course be solved with a select, but that's not the point of the question). I've used the <name> node to test that the constructed node set variable is in fact in the original tree and not a copy.
XSL version 1.0, processor is msxsl.
Non-working 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 input:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>X</name>
<entry>1</entry>
<entry>2</entry>
</root>
Wanted output:
X1X2
Actual output:
12
Of course the (or a) problem is the copy-of, but I can't work out a way around this.
There isn't a "way around it" in XSLT 1.0 - it's exactly how this is supposed to work. When you have a variable that is declared with content rather than with a select
then that content is a result tree fragment consisting of newly-created nodes (even if those nodes are a copy of nodes from the original tree). If you want to refer to the original nodes attached to the original tree then you must declare the variable using select
. A better question would be to detail the actual problem and ask how you could write a suitable select
expression to find the nodes you want without needing to use for-each
- most uses of xsl:if
or xsl:choose
can be replaced with suitably constructed predicates, maybe involving judicious use of xsl:key
, etc.
In XSLT 2.0 it's much more flexible. There's no distinction between node sets and result tree fragments, and the content of an xsl:variable
is treated as a generic "sequence constructor" which can give you new nodes if you construct or copy them:
<xsl:variable name="example" as="node()*">
<xsl:copy-of select="//entry" />
</xsl:variable>
or the original nodes if you use xsl:sequence
:
<xsl:variable name="example" as="node()*">
<xsl:sequence select="//entry" />
</xsl:variable>
这篇关于构建而不是选择 XSL 节点集变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!