我无法理解exsl:node-set函数的工作原理。
我有一些XML,我正在扩展并使用它来动态填充exsl:node-set。我们说它目前采用以下格式:
<xsl:variable name="wrap">
<nodes>
<node/>
<node/>
<node/>
</nodes>
</xsl:variable>
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)"/>
这可以根据需要工作并输出$ wrapNodeSet显示上面的节点标记。根节点名称使用名称显示为“节点”($ wrapNodeSet /*).
现在我需要扩展它以拥有2个节点并动态填充节点集。所以:
<xsl:variable name="wrap">
<nodes tier="a">
<node/>
<node/>
<node/>
</nodes>
<nodes tier="b">
<node/>
<node/>
<node/>
</nodes>
</xsl:variable>
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)/nodes[@tier='b']"/>
输出节点集包括nodes元素,但输出根节点的名称现在更改为'node'。
有人可以解释为什么仍然输出nodes元素吗?
答案 0 :(得分:0)
如果我正确地理解了你的问题,我相信“直观地”发生的事情(实际的幕后实现细节可能有点不同)在第一个例子中,你的变量指向'匿名节点集'包装<nodes>
元素的变量。因此,name($wrapNodeSet/*)
获取此匿名节点集的所有直接子节点的名称,在这种情况下,它只是单个<nodes>
元素的名称。
在第二种情况下,您比匿名节点集更深入,变量直接包含单个nodes[@tier='b']
元素。在这种情况下,name($wrapNodeSet/*)
会选择该<nodes>
元素的所有直接子元素,并将返回3个<node>
个实例。如果你对此选择值为select,它将默认只显示第一个值,这就是你在输出中只看到“node”的原因。
要获取第二个实例的根名称,只需直接执行name($wrapNodeSet)
即可看到“节点”。在第一个实例中执行$name(wrapNodeSet)
将不会返回任何内容,因为匿名节点集没有名称。
答案 1 :(得分:0)
<xsl:variable name="wrapNodeSet"
select="exsl:node-set($wrap)/nodes[@tier='b']"/>
这将从使用nodes
扩展程序获取的树中选择任何node-set()
元素,(nodes
元素)具有值为tier
的{{1}}属性
然后:
'b'
生成name($wrapNodeSet/*)
中包含的第一个节点的第一个子元素的名称。由于$wrapNodeSet
只包含一个$wrapNodeSet
元素,而nodes
元素只包含nodes
个子元素,因此第一个这样的子元素是node
元素及其name,因为任何node
元素的名称为node
。
为什么你会在这个结果中看到任何意想不到的结果?
换句话说:
"node"
在ext:node-set()
上的应用在两种情况下产生相同的树,但在第二种情况下,您对$wrap
的结果使用不同的,更长的XPath表达式 - 因此从评估这两个不同的XPath表达式得到的结果不同。
答案 2 :(得分:0)
exslt:node-set有一个非常非正式的规范,并且可能有关于哪些实现彼此不同的详细信息。在边缘情况下肯定是这样,例如,如果exstl:node-set的参数不是结果树片段,会发生什么。
我期望的行为是exslt:node-set()总是提供“根节点”(XPath 2.0称之为“文档节点”)。 XPath 1.0中定义的根节点没有名称。在第一个示例中,根节点有一个名为“nodes”的元素子节点。在第二个示例中,根节点有两个元素子节点,两个元素都具有名称“nodes”。
您说“输出根节点的名称现在更改为'node'” - 这令人困惑,因为XPath 1.0中的“根节点”定义了术语永远不会有名称。你实际输出了什么?