如果我在没有指定值的情况下使用<xsl:param>
,变换器会假定该值为空字符串。
换句话说,如果我忘记指定一个值(例如<xsl:param name="N"/>
),编译器就不会发出错误信号。这可能导致我的程序无声地失败,这是一件坏事。
如何指定我的<xsl:param>
必须具有明确值?例如,此代码应该给我一个错误,因为没有指定显式值:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:call-template name="F1"></xsl:call-template>
<html>
<head>
<title></title>
</head>
<body>stuff</body>
</html>
</xsl:template>
<xsl:template name="F1">
<xsl:param name="N"/> <!-- I Should Get An Error Here! -->
</xsl:template>
</xsl:stylesheet>
我正在寻找XSLT 1.0和XSLT 2.0中的解决方案。
答案 0 :(得分:5)
在XSLT 2.0中,您当然可以说<xsl:param required="yes">
,因此问题就会消失。
答案 1 :(得分:2)
你可以用一些meta-XSLT实际做到这一点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="xsl:call-template">
<xsl:variable name="template" select="/xsl:stylesheet/xsl:template[@name=current()/@name]"/>
<xsl:variable name="call" select="." />
<xsl:variable name="desc">
<xsl:value-of select="concat('call to named template "',$template/@name,'" in ')"/>
<xsl:choose>
<xsl:when test="ancestor::xsl:template/@name">
<xsl:value-of select="concat('named template "',ancestor::xsl:template/@name,'"')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('template matching "',ancestor::xsl:template/@match,'"')" />
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
</xsl:variable>
<xsl:for-each select="$template/xsl:param[not(@select)]">
<xsl:if test="not($call/xsl:with-param[@name=current()/@name])">
<xsl:value-of select="concat('Missing parameter "',@name,'" in ',$desc)" />
</xsl:if>
</xsl:for-each>
<xsl:for-each select="xsl:with-param">
<xsl:if test="not($template/xsl:with-param[@name=current()/@name])">
<xsl:value-of select="concat('Unrecognised parameter "',@name,'" in ',$desc)" />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
此样式表将任何样式表作为输入,并检查所有调用模板是否具有正确的参数,如果有任何错误则输出消息。
这显然不会将错误检查放在变换器本身,但它会一次性列出所有错误,并且可以扩展以检查其他问题。
编辑:我已经对它进行了调整以处理可选参数,并以描述错误位置的方式添加;它实际上是一个重新设计,可选参数只是计算它们将是棘手的,所以我删除了那一点。无论如何,每个错误都是逐条列出的,因此计数并不是必需的。
答案 2 :(得分:1)
<xsl:param name="foo" select="false" />
<xsl:if test="not($foo)">
<xsl:message terminate="yes">You called me with improper params</xsl:message>
</xsl:if>
答案 3 :(得分:1)
一种简单的方法是检查输入参数不是空字符串(注释中提到的特定情况):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="test">
<xsl:param name="nodefault"/>
<xsl:choose>
<xsl:when test="boolean($nodefault)">
<xsl:message>do your stuff</xsl:message>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">Your stuff can't be done</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="test"/>
</xsl:template>
</xsl:stylesheet>
或更简单:
<xsl:template name="test">
<xsl:param name="nodefault"/>
<xsl:if test="not($nodefault)">
<xsl:message terminate="yes">Your stuff can't be done</xsl:message>
</xsl:if>
<!-- do your stuff -->
</xsl:template>
答案 4 :(得分:1)
有一个类似的选项,您可以使用一个变量来选择被调用模板中的参数,例如:
<xsl:template match="/">
<!-- call 1 -->
<xsl:apply-templates select="//encabezado/usuario" mode="forma1">
<xsl:with-param name="nombre" select="'wwww1'"/>
</xsl:apply-templates>
<!-- call 2 -->
<xsl:apply-templates select="//encabezado/usuario" mode="forma1">
</xsl:apply-templates>
<xsl:template match="node()" mode="forma1">
<xsl:param name="nombre"/>
<xsl:param name="valor"/>
<xsl:variable name="nombreLocal">
<xsl:choose>
<xsl:when test="normalize-space($nombre)">
<xsl:value-of select="$nombre"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="local-name()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select ="$nombreLocal"/>
</xsl:template>