如何在没有"select"属性的<xsl:param>上强制错误?



如果在不指定值的情况下使用<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>

我正在寻找XSLT1.0和XSLT2.0的解决方案。

在XSLT2.0中,当然可以说<xsl:param required="yes">,这样问题就消失了。

您实际上可以使用一些元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 &quot;',$template/@name,'&quot; in ')"/>
      <xsl:choose>
        <xsl:when test="ancestor::xsl:template/@name">
          <xsl:value-of select="concat('named template &quot;',ancestor::xsl:template/@name,'&quot;')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat('template matching &quot;',ancestor::xsl:template/@match,'&quot;')" />
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>&#10;</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 &quot;',@name,'&quot; 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 &quot;',@name,'&quot; in ',$desc)" />
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="text()" />
</xsl:stylesheet>

该样式表将任何样式表作为输入,并检查所有调用模板是否具有正确的参数,如果有任何错误,则输出消息。

这显然不会将错误检查放在转换器本身中,但它会一次性列出所有错误,并可能扩展到检查其他问题。

编辑:我对它进行了调整,以处理可选参数,并添加了一种描述错误所在的方法;这实际上有点像重新设计,使用可选参数——简单地计算它们——会很棘手,所以我删除了这一点。无论如何,每个错误都是逐项列出的,所以计数并不是真正必要的。

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

一个简单的方法是检查输入参数是否为空字符串(注释中提到的特定情况(:

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

还有一个类似的选项,您可以使用一个变量来选择被调用模板中的参数,例如:

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

相关内容

  • 没有找到相关文章

最新更新