我正在使用Saxon 9.4和XSLT 2.0
我的样式表中有以下代码段: -
<xsl:template name="some_template">
<xsl:param name="some_param" as="xs:integer?"/>
</xsl:template>
这基本上是一个接受可选整数参数的模板。但是,当我尝试这样称呼时,
<xsl:call-template name="some_template>
<xsl:with-param name="some_param">
<xsl:if test="some_condition">
<xsl:value-of select="xs:integer(./@attr div 20)"/>
</xsl:if>
</xsl:with-param>
</xsl:call-template>
我收到一条错误消息: -
Validation error FORG0001: Cannot convert zero-length string to an integer
但是,以下两个样式表不会给我一个错误: -
<xsl:call-template name="some_template>
<xsl:with-param name="some_param">
<xsl:value-of select="xs:integer(./@attr div 20)"/>
</xsl:with-param>
</xsl:call-template>
或
<xsl:variable name="dummy" as="xs:integer?">
<xsl:if test="some_condition">
<xsl:value-of select="xs:integer(./@attr div 20)"/>
</xsl:if>
</xsl:variable>
<xsl:call-template name="some_template>
<xsl:with-param name="some_param" select="$dummy"/>
</xsl:call-template>
很明显,整个街区没有保留类型信息。知道如何让第一件事工作吗?第三个样式表做了我想要的语义,但我宁愿不去创建(几个)虚拟变量只是为了能够做到这一点。
谢谢!
答案 0 :(得分:1)
我认为当你的<xsl:if>
为假时错误意味着你的参数没有分配值。您可以尝试以下解决方案之一:
您是否尝试为<xsl:param>
设置默认值?
<xsl:template name="some_template">
<xsl:param name="some_param" select="-1" as="xs:integer?" />
</xsl:template>
false
案例使用XPath2.0 if-then-else expression调用模板时始终设置值:
<xsl:call-template name="some_template>
<xsl:with-param name="some_param" select="
if (some_condition)
then xs:integer(./@attr div 20)
else -1"
/>
</xsl:call-template>
我使用-1
作为false
案例的值。
答案 1 :(得分:1)
此转化:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:call-template name="some_template">
<xsl:with-param name="some_param" select=
"if(some_condition)
then xs:integer(@attr div 20)
else ()
"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="some_template">
<xsl:param name="some_param" as="xs:integer?"/>
XXX
</xsl:template>
</xsl:stylesheet>
应用于以下每个XML文档时:
<t attr="20">
<some_condition/>
</t>
,
<t>
<some_condition/>
</t>
,
<t attr="20">
</t>
和
<t>
</t>
产生想要的正确结果(不会产生任何异常):
XXX
答案 2 :(得分:1)
我并不完全清楚这里发生了什么,但很清楚的是如何改进你的代码,这样就不会那么混乱了。使用您编写的代码,在真实情况下,您正在计算double,将其转换为整数,将整数转换为文本节点,将其包装在文档节点中,将文档节点作为参数传递,将此雾化为无类型接收端的原子,因为期望的类型是原子的,然后将无类型的原子值转换为整数。所有这一切都应该有效,但是非常迂回,并且很容易通过xsl:with-param上的“as =”xs:integer“”来避免。
在false的情况下,您传递的文件节点没有子节点,并将其转换为xs:integer?将失败 - 它不会转换为空序列。所以,尽管你说的话,我认为它在错误的道路上失败了。