0

谁能给我解释一下?(使用最新的 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>呢?

@attrib is顺便说一句:不存在时一切都是正确的。这里使用的副本用于调试;原来的用法是将 XPath 结果转换为数字,缺少的属性不会导致 NaN,而是某个默认值。

4

2 回答 2

1

这个版本的 exsl:node-set() 大概会创建一个与节点 @attrib 位于不同树中的节点。当两个节点位于不同的树中时,取决于实现,它们中的哪一个在文档顺序中位于首位。该构造(X|Y)[position()=1](或等效地(X|Y)[1])选择 X 和 Y 中的任何一个在文档顺序中排在第一位。因此,它选择 X 还是 Y 本质上是不可预测的。

于 2011-12-18T00:49:02.577 回答
1

来自 OP 的评论:

好的,这意味着我唯一的选择是使用<xsl:choose>...,对吗?

虽然由于@Michael Kay 和我在我的评论中解释的原因,您尝试它的方式会产生不可预测的结果,但仍然有方法可以做您想做的事情(产生attrib属性的值或默认值 ( 0)

concat(@attrib,
       substring(0, 2 -not(@attrib))
       )

这会产生attrib属性的值(如果存在此属性)或(如果不存在)默认值0

完整的 XSLT 解决方案

<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>

当此转换应用于以下 XML 文档时

<t>
 <x attrib="abc"/>
 <x/>
</t>

产生了想要的正确结果

 abc

==========

 0

==========
于 2011-12-18T03:27:32.990 回答