Appendix B. Debugging XSL stylesheets

Table of Contents

Inserting messages
Using an XSLT debugger

If you are customizing the stylesheets, there will be times when your changes don't produce the results you expected. To find out what is going wrong, you will need to go through a debugging process. Here are methods you can use.

Inserting messages

The simplest debugging technique is to output debugging messages from specific locations in the templates to tell you what is going on. A message can report the value of a variable or parameter, or list the content of the element currently being processed. That information will help you decide if your code is doing the right thing.

You use the xsl:message element to output a debugging message. The content of that element does not go to the standard output where it would mix in with your HTML or FO output. Instead, it goes to the error output (called standard error on Unix). The message can contain plain text, and it can contain XSL elements that generate output. Here is an example that reports the value of a parameter:

<xsl:message>In lists.xsl (match="itemizedlist"), the value of the 
css.decoration parameter is <xsl:value-of select="$css.decoration"/>
</xsl:message>

The text provides the context for the message, and the xsl:value-of element outputs the value of the parameter.

Here are some hints for using this method:

  • Be sure to include enough context in the message so you know where it is coming from. The order of processing by XSLT is often not intuitive, and may not follow the order of the document. Since the messages are in an output stream separate from the content, it won't be obvious where a message is coming from unless you indicate such. There is no provision in the XSL standard for indicating line numbers of either the input file or the stylesheet.

  • If you need to know the name of the current element being processed, then include something like this:

    <xsl:value-of select="local-name(.)"/>
  • If you need to know the value of an attribute on the current element, then include something like this:

    <xsl:value-of select="@valign"/>

    If the element currently being processed does not have that attribute, then this will be blank.

  • If you want to know the content of the element being processed, you can do this:

    <xsl:value-of select="."/>

    When xsl:value-of selects an element, you get the text content of the element and its children, without any markup. If the element has no text (such as imagedata), then there is no output.

  • Any extra whitespace (spaces, tabs, line breaks) in a message is collapsed to single spaces. If you want to insert a line break or indents in your message, use xsl:text. In this example, the message will be output on two lines with the second line indented. Since the second line break is after the closing tag of xsl:text, it is not preserved as a line break. Note that you cannot include other elements inside xsl:text, so it has to end before the xsl:value-of.

    <xsl:message><xsl:text>In lists.xsl (match="itemizedlist"), the value 
       of the css.decoration parameter is </xsl:text>
     <xsl:value-of select="$css.decoration"/></xsl:message>
    
  • Don't insert your messages in the original DocBook stylesheet files. Copy the XSL file you want to modify to a different location and include it in a customization layer. When you have solved the problem you can just delete the modified file, leaving your original stylesheet files intact.

Note

If you are using MSXML 3.0 as your processor, then your messages will be ignored unless you add the optional terminate="yes" attribute to your xsl:message, which terminates processing.

If you need your message to be inline with your output, then use xsl:comment instead of xsl:message. That will insert your message into your output, marked as a comment:

<!-- This is my message -->