任何人都可以向我解释这个吗? (使用最新的libxslt):
<a><xsl:copy-of select="(@attrib|exsl:node-set(0))"/></a>
<b><xsl:copy-of select="(@attrib|exsl:node-set(0))[position()=1]"/></b>
<x><xsl:copy-of select="(@attrib|exsl:node-set(0))[1]"/></x>
<xsl:variable name="value" select="@attrib"/>
<y><xsl:copy-of select="($value|exsl:node-set(0))[1]"/></y>
结果(对于当前节点的@attrib = 1):
<a attrib="1">0</a>
<b attrib="1"/>
<x>0</x>
<y attrib="1"/>
<a>
和<b>
显示预期的行为
<x>
是恕我直言,不正确
但为什么确实将@attrib
放入变量“修复”<y>
?
BTW:当@attrib is
不存在时,一切都是正确的。这里使用的副本用于调试;原始用法将XPath结果转换为数字,并且缺少的属性不应导致NaN,而是导致某个默认值。
答案 0 :(得分:1)
此版本的exsl:node-set()可能会创建一个与节点@attrib位于不同树中的节点。当两个节点位于不同的树中时,它依赖于实现,其中哪个节点首先按文档顺序排列。构造(X|Y)[position()=1]
(或等效(X|Y)[1]
)选择X和Y中的任何一个按文档顺序排在第一位。因此,它是否选择X或Y基本上是不可预测的。
答案 1 :(得分:1)
来自OP的评论:
好的,这意味着我唯一的选择就是使用
<xsl:choose>
...,对吗?
虽然你尝试它的方式会产生不可预测的结果,原因是由@Michael Kay和我在评论中解释的原因,仍然有办法做你想做的事情(产生{{1的值)属性或默认值(attrib
):
0
这将生成concat(@attrib,
substring(0, 2 -not(@attrib))
)
属性的值(如果此属性存在)或(如果不存在)默认值attrib
。
完成XSLT解决方案:
0
将此转换应用于以下XML文档:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="x">
<xsl:value-of select=
"concat(@attrib,
substring('0', 2 -not(@attrib))
)"/>
==========
</xsl:template>
</xsl:stylesheet>
产生了想要的正确结果:
<t>
<x attrib="abc"/>
<x/>
</t>