是否可以使用xsl:choose
从rtf创建节点集变量(用于MSXML引擎)?
我有以下结构:
<xsl:choose>
<xsl:when test="function-available('msxsl:node-set')">
<xsl:variable name="colorList" select="msxsl:node-set($std:colorList)"/>
<xsl:for-each select="$colorList/color">
tr.testid<xsl:value-of select="@testid"/> {
color:<xsl:value-of select="."/>;
}
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="colorList" select="$std:colorList"/>
<xsl:for-each select="$colorList/color">
tr.testid<xsl:value-of select="@testid"/> {
color:<xsl:value-of select="."/>;
}
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
std:colorList
当然是树片段。
以上工作正常,并且没问题,因为两个备选方案的代码相同,但不是那么大
但是对于更大的代码片段,我想知道是否可以通过首先根据rtf声明变量来避免重复代码,然后执行代码;
<xsl:variable name="colorList">
<xsl:choose>
<xsl:when test="function-available('msxsl:node-set')">
<xsl:copy-of select="msxsl:node-set($std:colorList)"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$std:colorList"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:for-each select="$colorList/color">
tr.testid<xsl:value-of select="@testid"/> {
color:<xsl:value-of select="."/>;
}
</xsl:for-each>
但这不能正常工作:MSXML抱怨colorList
不是节点集,因此无法在xsl:for-each
中使用它。
XSL transformation failed due to following error:
Expression must evaluate to a node-set.
-->$colorList<--/color
请注意,在工作示例中,由于将std:colorList
“复制”到colorList
变量中,因此未发生此错误。显然它是一个xsl解析错误,而不是运行时错误
我应该使用除xsl:copy-of
之外的其他内容吗?还是有另一种方法可以实现同样的目标吗?
如果您想知道,std:colorList
内容如下:
<std:colorList>
<color testid="111">#FF0000</color>
<color testid="999">#FFFF00</color>
</std:colorList>
答案 0 :(得分:3)
不幸的是,在XSLT 1.0中,当xsl:variable包含指令而不是select属性时,结果始终是RTF。因此,您将RTF转换为节点集的细致尝试将一事无成,因为它会再次直接转换回来。
我担心没有干净的解决方法(当然,除了转向XSLT 2.0)。我建议像这样构建代码:
<xsl:choose>
<xsl:when test="function-available('msxsl:node-set')">
<xsl:apply-templates select="msxsl:node-set($std:colorList)/color" mode="z"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$std:colorList/color" mode="z"/>
</xsl:otherwise>
</xsl:choose>
<xsl:template match="color" mode="z">
tr.testid<xsl:value-of select="@testid"/> {
color:<xsl:value-of select="."/>;
}
</xsl:template>
答案 1 :(得分:0)
仅供记录,我在下面添加最终解决方案。它与迈克尔提出的略有不同,在应用模板之前将RTF的副本添加到变量中 这是因为否则MSXML在xsl解析期间仍然是错误的(显然它检查apply-templates选择值并且当它是RTF而不是节点集时结束它是不正确的。并且,正如迈克尔所说,xsl:variable select属性就是这样:将RTF转换为节点集。
<xsl:choose>
<xsl:when test="function-available('msxsl:node-set')">
<xsl:apply-templates select="msxsl:node-set($std:colorList)/color" mode="addTRclassToCSS"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="colorList" select="$std:colorList"/>
<xsl:apply-templates select="$colorList" mode="addTRclassToCSS"/>
</xsl:otherwise>
</xsl:choose>
<xsl:template match="color" mode="addTRclassToCSS">
tr.testid<xsl:value-of select="@testid"/> {
color:<xsl:value-of select="."/>;
}
</xsl:template>