Xslt xsl:sequence是否始终为非空?
我不理解此样式表的输出:Xslt xsl:sequence是否始终为非空?,xslt,xpath,xslt-2.0,xsl-variable,Xslt,Xpath,Xslt 2.0,Xsl Variable,我不理解此样式表的输出: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:apply-templates select="root/sub"/> </xsl:template> <xsl:template match="sub"&g
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/sub"/>
</xsl:template>
<xsl:template match="sub">
<xsl:variable name="seq">
<xsl:sequence select="*" />
</xsl:variable>
<xsl:message>
<xsl:value-of select="@id" />
<xsl:text>: </xsl:text>
<xsl:value-of select="count($seq)" />
</xsl:message>
</xsl:template>
</xsl:stylesheet>
我本来以为是这样的:
empty: 0
one: 1
two: 2
three: 3
为什么在这种情况下,
count($seq)
总是返回1?如何更改变量定义,以便我以后可以测试它是否为空?(简单的
将返回预期的答案,但不是一个选项…我想在中的变量之间更改,稍后测试它是否为空)。您正在选择子节点,然后对每个节点进行计数-因此它始终为1。您需要计算孩子数,例如:
<xsl:value-of select="count($seq/*)" />
将提供您期望的输出。让我试着回答您问题的“为什么”部分
如果您编写以下语句:
<xsl:variable name="x" select="*" />
其中变量$x
包含一个节点序列:内容的父节点。在这里,count($x)
将始终为您提供1
。要获取内容
元素的数量,需要对$x
隐式根节点的子节点进行计数:计数($x/content)
根据经验,您可以记住:如果xsl:variable
本身是一个带有select
属性的空元素,那么结果集将被分配给变量。如果使用xsl:variable
而不使用select
属性,则始终使用该变量创建一个隐式父级,并且该变量的内容是它下面的子级
这同样适用于将xsl:sequence
作为xsl:variable
的子对象的示例。通过使用非空的xsl:variable
可以为序列创建一个隐式父级,这就是为什么如果计算变量本身,总是得到1
如果您同时需要:xsl:variable
中的一组语句,但是select
属性的行为,则可以使用以下方法解决此问题:
<xsl:variable name="x">
<content />
<content />
</xsl:variable>
<xsl:variable name="x" select="$y/*" />
<xsl:variable name="y">
<xsl:sequence select="foo" />
</xsl:variable>
这将产生count($x)
的预期金额,但这是否真的有益或使代码更清晰是有争议的。如果将变量声明更改为:
<xsl:variable name="seq" select="*"/>
谢谢你的回答。但我不确定我是否理解。。。myseq
变量中究竟存储了什么(例如,当从samle输入处理时)。我以为这是两个1
元素的序列。非常感谢!为了便于参考,这里是文档相关部分的链接(如果我理解正确的话):是的,您确实理解正确。规范的这一部分显示您隐式地拥有一条xsl:document
指令。它还指出了我没有提到的其他内容:如果需要特定的输出类型,可以使用as
属性。xsl:variable
中的序列必须可转换为此类型,否则会发生错误。感谢您提供item()*
和explain
提示(是的,我使用saxon)。
<xsl:variable name="x" select="$y/*" />
<xsl:variable name="y">
<xsl:sequence select="foo" />
</xsl:variable>
<xsl:variable name="seq" select="*"/>
<xsl:variable name="seq" as="item()*">
<xsl:sequence select="*" />
</xsl:variable>
<xsl:template match="sub" saxon:explain="yes" xmlns:saxon="http://saxon.sf.net/">
<xsl:variable name="seq">
<xsl:sequence select="*" />
</xsl:variable>
<xsl:message>
<xsl:value-of select="@id" />
<xsl:text>: </xsl:text>
<xsl:value-of select="count($seq)" />
</xsl:message>
</xsl:template>
Optimized expression tree for template at line 6 in :
let $seq[refCount=1] as document-node() :=
document-constructor
child::element()
return
message