2011-06-30 1 views
3

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

Am ищет решение как в XSLT 1.0 и XSLT 2.0.

+0

Просто опускают присвоение значения в param. В чем проблема? –

+0

, если я опускаю присвоение значения в объявлении параметра и не предоставляю параметр, ошибки не генерируются. трансформатор предполагает, что мне нужно значение по умолчанию пустой строки и продолжить преобразование без каких-либо ошибок. Я хочу сказать трансформатору, что этот параметр не имеет значения по умолчанию, поэтому, когда я не укажу явно его ошибку, трансформатор должен дать мне предупреждение/ошибку вместо того, чтобы продолжать, как если бы это была не ошибка , – NorvayHais

ответ

2

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

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

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

EDIT: Я адаптировал его для обработки необязательных параметров и добавил в средство описания, где ошибка; это на самом деле немного редизайн, с дополнительными параметрами просто подсчет их будет сложным, поэтому я удалил этот бит. В любом случае каждая ошибка отображается, поэтому счет действительно не нужен.

+0

спасибо, эта идея замечательная. однако soution не работает. Я включил два теста в мой отредактированный вопрос. Он не работает для второго теста. второй тестовый пример должен быть безошибочным тестовым примером, но ваше решение считает, что оно имеет ошибки. – NorvayHais

+0

Это связано с тем, что не учитывается возможность дополнительных параметров; Я могу починить это. – Flynn1179

+0

спасибо m8. вы не представляете, насколько это полезно! (Кстати, это будет здорово, если вы сможете обновить решение таким образом, чтобы оно не выводило содержимое, потому что прямо сейчас, если мы берем тестовый ввод, он выводит ** материал **, который действительно не требуется) – NorvayHais

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

это не работает. если я делаю '' Он дает мне сообщение об ошибке. Но поскольку я явно указал значение параметра, он не должен давать мне никаких ошибок. – NorvayHais

+0

Какая ошибка?Xslt должен завершиться сообщением «Вы назвали меня с неправильными параметрами» – PhillyNJ

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

просто быстрый вопрос относительно кода. я видел, что вы использовали 'not (boolean ($ nodefault)), но не правда ли, что' boolean() 'подразумевается и просто' not ($ nodefault) 'будет конвертировать' $ nodefault' в boolean first перед тем как положить преобразованное логическое значение через функцию 'not()'? – NorvayHais

+0

Да. Правильно, я был немного доволен :) –

+0

спасибо за помощь. но есть ли * общее решение для проблемы? Мне нравится ваша идея установить значение, которое будет признано «неправильным». Однако это не сработает, если я явно вызову-шаблон с этим «неправильным значением», так как он вызовет ошибку. Это не то, что я хотел. Если я поставил параметр с параметром, то независимо от того, какое значение имеет значение с параметром с параметром (даже если это пустое значение), ошибок не должно быть. – NorvayHais

4

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

+0

Но XSLT 2.0 недоступен ...... – NorvayHais

+1

Тогда почему вы отметили вопрос xslt-2.0? –

+0

Я отметил его оба. В одной системе XSLT 2.0 недоступен. – NorvayHais

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> 
Смежные вопросы