Как заставить ошибки набез атрибута "выбрать"? - PullRequest
3 голосов
/ 30 июня 2011

Если я использую <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.

Ответы [ 5 ]

5 голосов
/ 30 июня 2011

Конечно, в XSLT 2.0 можно сказать <xsl:param required="yes">, поэтому проблема исчезнет.

2 голосов
/ 30 июня 2011

Вы могли бы сделать это с небольшим количеством мета-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>

Эта таблица стилей берет любую таблицу стилей в качестве входных данных и проверяет, что все шаблоны вызовов имеют правильные параметры, выводя сообщение при наличии ошибок.

Это, очевидно, не будет помещать проверку ошибок в сам преобразователь, но будет перечислять ВСЕ ошибки за один раз и потенциально может быть расширен для проверки других проблем.

РЕДАКТИРОВАТЬ: я адаптировал его для обработки необязательных параметров, и добавил средства для описания, где ошибка; на самом деле это немного редизайн, с необязательными параметрами, просто подсчитать их будет сложно, поэтому я удалил этот бит. В любом случае, все ошибки детализированы, поэтому подсчет не был действительно необходим.

1 голос
/ 15 октября 2013

Есть аналогичная опция, где вы можете использовать переменную, которая выбирает параметр в вызываемом шаблоне, например:

<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>
1 голос
/ 30 июня 2011

Простой способ проверить, что входной параметр не является пустой строкой (конкретный случай упомянут в вашем комментарии):

<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>
1 голос
/ 30 июня 2011
<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>
...