当$world
是元素列表时,这三个块在副作用方面有何不同?我看到第一个和第三个之间有不同的行为,无法理解它。
<xsl:variable name="hello" select="$world" />
<xsl:variable name="hello">
<xsl:value-of select="$world" />
</xsl:variable>
<xsl:variable name="hello">
<xsl:choose>
<xsl:when test="$something=true()">
<xsl:value-of select="$world" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$world" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
编辑1:我想在$hello
中处理<xsl:for-each select="$hello">
。使用上面的第三个块<xsl:for-each>
只有一个要处理的项目,其中包含$world
的连接内容。那是为什么?
答案 0 :(得分:2)
第一个xsl:variable
的值和类型与$world
相同。第二个是结果树片段,其中单个文本节点的字符串值为$world
。第三个也是一个带有单个文本节点的结果树片段。
我想你想要
<xsl:variable name="hello" select="if (condition) then $world else $foo"/>
在XSLT 2.0中,然后你的for-each select="$hello"
可以按你的需要工作,或者在你想要的XSLT 1.0和EXSLT中使用
<xsl:variable name="hello">
<xsl:choose>
<xsl:when test="condition">
<xsl:copy-of select="$world"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$foo"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:for-each select="exsl:node-set($hello)/*">...</xsl:for-each>
答案 1 :(得分:1)
虽然所有三个示例在XSLT 1.0和XSLT 2.0中都有效,但描述语义的方式在两个规范中是非常不同的。当$ value包含多个节点时,<xsl:value-of select="$value"/>
的效果取决于样式表是指定version =“1.0”还是version =“2.0”。
要记住的主要事项,适用于两个版本,是(a)xsl:value-of通过将其选择的任何内容转换为字符串来创建文本节点,以及(b)xsl:包含指令的变量(并且不“as”属性创建一个以文档节点为根的新树。
答案 2 :(得分:0)
<xsl:variable name="hello"> <xsl:choose> <xsl:when test="$something=true()"> <xsl:value-of select="$world" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$world" /> </xsl:otherwise> </xsl:choose> </xsl:variable>
我想在a中处理
$hello
<xsl:for-each select="$hello">
。同<xsl:for-each>
上方的块有 只包含一个要处理的项目$world
的联合内容。为什么是 是什么?
名为$hello
的变量包含字符串值$world
。根据定义,这是<xsl:value-of>
在XSLT 1.0中的行为。
您没有向我们展示如何定义$world
,但如果它包含单个元素或整个文档树,那么(再次)按照定义,其字符串值是连接(按文档顺序)它的所有后代 - 文本节点。
这正是你所看到的。
如果是:
,则情况会有所不同<xsl:value-of select="$world" />
您使用:
<xsl:copy-of select="$world" />
这将复制整个子树,其根是/
中包含的$world
包含完整文档的情况下的元素(或根节点$world
)。
但是,在XSLT 1.0中,这会创建所谓的RTF(结果树片段),根据定义,不能将RTF用作XPath(1.0)表达式中的位置步骤。
首先必须使用供应商提供的扩展函数将其转换为常规树(文档节点),该扩展函数通常具有本地名称node-set
,但在特定于供应商的命名空间中。
典型的例子是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vWorld" select="/*"/>
<xsl:template match="/">
<xsl:variable name="vrtfHello">
<xsl:copy-of select="$vWorld"/>
</xsl:variable>
<xsl:variable name="vHello" select=
"ext:node-set($vrtfHello)/*"/>
<xsl:copy-of select="$vHello/*[3]"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档时:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
结果(正如预期的那样):
<num>03</num>
这里我们在名称空间“http://exslt.org/common”中使用ext:node-set()
扩展函数,该函数由EXSLT独立于供应商的库指定。大多数XSLT 1.0处理器都支持EXSLT,并且使用其node-set()
扩展功能并不会降低所有此类XSLT处理器上XSLT应用程序的可移植性。