23 Diagnostics

23.1 Messages

<!-- Category: instruction -->
<xsl:message
  select? = expression
  terminate? = { boolean }
  error-code? = { eqname } >
  <!-- Content: sequence-constructor -->
</xsl:message>

The xsl:message instruction sends a message in an implementation-defined way. The xsl:message instruction causes the creation of a new document, which is typically serialized and output to an implementation-defined destination. The result of the xsl:message instruction is an empty sequence.

The content of the message may be specified by using either or both of the optional select attribute and the sequence constructor that forms the content of the xsl:message instruction.

If the xsl:message instruction contains a sequence constructor, then the sequence obtained by evaluating this sequence constructor is used to construct the content of the new document node, as described in 5.7.1 Constructing Complex Content.

If the xsl:message instruction has a select attribute, then the value of the attribute must be an XPath expression. The effect of the xsl:message instruction is then the same as if a single xsl:copy-of instruction with this select attribute were added to the start of the sequence constructor.

If the xsl:message instruction has no content and no select attribute, then an empty message is produced.

The tree produced by the xsl:message instruction is not technically a final result tree. The tree has no URI and processors are not required to make the tree accessible to applications.

Note:

In many cases, the XML document produced using xsl:message will consist of a document node owning a single text node. However, it may contain a more complex structure.

Note:

An implementation might implement xsl:message by popping up an alert box or by writing to a log file. Because the order of execution of instructions is implementation-defined, the order in which such messages appear is not predictable.

The terminate attribute is interpreted as an attribute value template.

If the effective value of the terminate attribute is yes, then the processor must signal a dynamic error after sending the message. This error may be caught in the same way as any other dynamic error using xsl:catch. The default value is no. Note that because the order of evaluation of instructions is implementation-dependent, this gives no guarantee that any particular instruction will or will not be evaluated before processing terminates.

The optional error-code attribute (also interpreted as an attribute value template) may be used to indicate the error code associated with the message. This may be used irrespective of the value of terminate. The effective value of the error code attribute is expected to be an EQName. If no error code is specified, or if the effective value is not a valid EQName, the error code will have local part XTMM9000 and namespace URI http://www.w3.org/2005/xqt-errors. User-defined error codes should be in a namespace other than http://www.w3.org/2005/xqt-errors. When the value of terminate is yes, the error code may be matched in an xsl:catch element to catch the error and cause processing to continue normally.

[ERR XTMM9000] When a transformation is terminated by use of <xsl:message terminate="yes"/>, the effect is the same as when a dynamic error occurs during the transformation. The default error code is XTMM9000; this may be overridden using the error-code attribute of the xsl:message instruction.

Example: Localizing Messages

One convenient way to do localization is to put the localized information (message text, etc.) in an XML document, which becomes an additional input file to the stylesheet. For example, suppose messages for a language L are stored in an XML file resources/L.xml in the form:

<messages>
  <message name="problem">A problem was detected.</message>
  <message name="error">An error was detected.</message>
</messages>

Then a stylesheet could use the following approach to localize messages:

<xsl:param name="lang" select="'en'"/>
<xsl:variable name="messages"
  select="document(concat('resources/', $lang, '.xml'))/messages"/>

<xsl:template name="localized-message">
  <xsl:param name="name"/>
  <xsl:message select="string($messages/message[@name=$name])"/>
</xsl:template>

<xsl:template name="problem">
  <xsl:call-template name="localized-message">
    <xsl:with-param name="name">problem</xsl:with-param>
  </xsl:call-template>
</xsl:template>

Any dynamic error that occurs while evaluating the select expression or the contained sequence constructor, and any serialization error that occurs while processing the result, does not cause the transformation to fail; at worst, it means that no message is output, or that the only message that is output is one that relates to the error that occurred.

Note:

An example of such an error is the serialization error that occurs when processing the instruction <xsl:message select="@code"/> (on the grounds that free-standing attributes cannot be serialized). Making such errors recoverable means that it is implementation-defined whether or not they are signaled to the user and whether they cause termination of the transformation. If the processor chooses to recover from the error, the content of any resulting message is implementation-dependent.

One possible recovery action is to include a description of the error in the generated message text.

23.2 Assertions

The xsl:assert instruction is used to assert that the value of a particular expression is true; if the value of the expression is false, and assertions are enabled, then a dynamic error occurs.

<!-- Category: instruction -->
<xsl:assert
  test = expression
  select? = expression
  error-code? = { eqname } >
  <!-- Content: sequence-constructor -->
</xsl:assert>

By default, assertions are disabled.

An implementation must provide an external mechanism to enable or disable assertion checking. This may work either statically or dynamically, and may be at the level of the stylesheet as a whole, or at the level of an individual package, or otherwise. The detail of such mechanisms is implementation-defined.

If assertion checking is enabled, the instruction is evaluated as follows:

  1. The expression in the test attribute is evaluated. If the effective boolean value of the result is true, the assertion succeeds, and no further action is taken. If the effective boolean value is false, or if a dynamic error occurs during evaluation of the expression, then the assertion fails.

  2. If the assertion fails, then the effect of the instruction is governed by the rules for evaluation of an xsl:message instruction with the same select attribute, error-code attribute, and contained sequence constructor, and with the value terminate="yes". However, the default error code if the error-code attribute is omitted is XTMM9001 rather than XTMM9000.

    Note:

    To the extent that the behavior of xsl:message is implementation-defined, this rule does not prevent an implementation treating xsl:assert and xsl:message differently.

    Note:

    If evaluation of the test expression fails with a dynamic error, the effect is exactly the same as if the evaluation returns false, including the fact that the instruction fails with error code XTMM9001.

  3. If an assertion fails, then the following sibling instructions of the xsl:assert instruction are not evaluated.

    Note:

    This means that xsl:assert can be used (rather like xsl:if and xsl:choose) to prevent subsequent instructions from executing if a particular precondition is not true, which might be useful if the subsequent instructions have side-effects (for example, by calling extension functions) or if they can fail in uncatchable ways (for example, non-terminating recursion). It is worth noting that there are limits to this guarantee. It does not ensure, for example, that when an assertion within a template fails, the following siblings of the xsl:call-template instruction that invokes that template will not be evaluated; nor does it ensure that if an assertion fails while processing the first item of a sequence using xsl:for-each, then subsequent items in the sequence will not be processed.

[ERR XTMM9001] When a transformation is terminated by use of xsl:assert, the effect is the same as when a dynamic error occurs during the transformation. The default error code is XTMM9001; this may be overridden using the error-code attribute of the xsl:assert instruction.

As with any other dynamic error, an error caused by an assertion failing may be trapped using xsl:try: see 8.3 Try/Catch.

The result of the xsl:assert instruction is an empty sequence.

Example: Using Assertions with Static Parameters

The following example shows a stylesheet function that checks that the value of its supplied argument is in range. The check is performed only if the static parameter $DEBUG is set to true.

<xsl:param name="DEBUG" as="xs:boolean" select="false()" 
           static="yes" required="no"/>
<xsl:function name="f:days-elapsed" as="xs:integer">
  <xsl:param name="date" as="xs:date"/>
  <xsl:assert use-when="$DEBUG" test="$date lt current-date()"/>
  <xsl:sequence select="(current-date() - $since) 
                            div xs:dayTimeDuration('PT1D')"/>
</xsl:function>

Note:

Implementations should avoid optimizing xsl:assert instructions away. As a guideline, if the result of a sequence constructor is required by the transformation, the implementation should ensure that all xsl:assert instructions in that sequence constructor are evaluated. Conversely, if the result of a sequence constructor is not required by the transformation, its xsl:assert instructions should not be evaluated.

This guidance is not intended to prevent optimizations such as lazy evaluation, where evaluation of a sequence constructor may finish early, as soon as enough information is available to evaluate the containing instruction.

An implementation may provide a user option allowing a processor to treat assertions as being true without explicit checking. This option must not be enabled by default. If such an option is in force, the effect of any assertion not being true is implementation-dependent.

Note:

For example, given the assertion <xsl:assert test="count(//title)=1"/>, a processor might generate code for the expression <xsl:value-of select="//title"/> that stops searching for title elements after finding the first one. In the event that the source document contains more than one title, execution of the stylesheet may fail in arbitrary ways, or it may produce incorrect output.