Make your own free website on

A static code quality tool, for XSLT code

I am pleased to share a little tool with the XSLT community, which I feel has a potential to improve the quality of XSLT code.

The tool can be downloaded from, here.

This is a very light weight tool, and consists of just two files:

1. xslqual.xsl

This is the main file for this tool, and is the entry point to run it.

2. rules.xml

This is a ruleset file, which consists of a number of XSLT code quality rules. Each rule in this file is in a form of an XML fragment, something like following:

<rule name="DontUseDoubleSlashOperatorNearRoot">
        Avoid using the operator // near the root of a large tree
        //(@match | @select)[starts-with(., '//')]
        <!-- VIOLATION -->
        <xsl:variable name="x" select="//x/y/z" />

        <!-- REPAIR -->
        <xsl:variable name="x" select="/a/b/x/y/z" />

The following rules are supported out of the box, with this tool:

1. DontUseDoubleSlashOperatorNearRoot: Avoid using the operator // near the root of a large tree.

2. DontUseDoubleSlashOperator: Avoid using the operator // in XPath expressions.

3. SettingValueOfVariableIncorrectly: Assign value to a variable using the 'select' syntax if assigning a string value.

4. EmptyContentInInstructions: Don't use empty content for instructions like 'xsl:for-each' 'xsl:if' 'xsl:when' etc.

5. DontUseNodeSetExtension: Don't use node-set extension function if using XSLT 2.0.

6. RedundantNamespaceDeclarations: There are redundant namespace declarations in the xsl:stylesheet element.

7. UnusedFunction: Stylesheet functions are unused.

8. UnusedNamedTemplate: Named templates in stylesheet are unused.

9. UnusedVariable: Variable is unused in the stylesheet.

10. UnusedFunctionTemplateParameter: Function or template parameter is unused in the function/template body.

11. TooManySmallTemplates: Too many low granular templates in the stylesheet (10 or more).

12. MonolithicDesign: Using a single template/function in the stylesheet. You can modularize the code.

13. OutputMethodXml: Using the output method 'xml' when generating HTML code.

14. NotUsingSchemaTypes: The stylesheet is not using any of the built-in Schema types (xs:string etc.), when working in XSLT 2.0 mode.

15. UsingNameOrLocalNameFunction: Using name() function when local-name() could be appropriate (and vice-versa).

16. FunctionTemplateComplexity: The function or template's size/complexity is high. There is need for refactoring the code.

17. NullOutputFromStylesheet: The stylesheet is not generating any useful output. Please relook at the stylesheet logic.

18. UsingNamespaceAxis: Using the deprecated namespace axis, when working in XSLT 2.0 mode.

19. CanUseAbbreviatedAxisSpecifier:  Using the lengthy axis specifiers like child::, attribute:: or parent::node().

20. UsingDisableOutputEscaping: Have set the disable-output-escaping attribute to 'yes'. Please relook at the stylesheet logic.

21. NotCreatingElementCorrectly: Creating an element node using the xsl:element instruction when could have been possible directly.

22. AreYouConfusingVariableAndNode: You might be confusing a variable reference with a node reference. (contributed by, Alain Benedetti)

23. IncorrectUseOfBooleanConstants: Incorrectly using the boolean constants as 'true' or 'false'. (contributed by, Tony Lavinio)

24. ShortNames: Using a single character name for variable/function/template. Use meaningful names for these features.

25. NameStartsWithNumeric: The variable/function/template name starts with a numeric character.

The tool can be run in the following two ways:

(1) Processing a single input file

java net.sf.saxon.Transform -l source.xsl xslqual.xsl ruleset=rules.xml target=xml

The explanation of various parameters for this command are as follows:

-l    :    This option is required by Saxon to generate line numbers for nodes. Line numbers are generated in the violation report, which is helpful to locate the errors.

source.xsl    :    This specifies the source code (an XSLT file) to be analyzed.

xslqual.xsl    :    This is the main program for this tool.

ruleset=rules.xml    :    This parameter specifies the ruleset file.

target=xml    :    This parameter specifies the format of the output. The output formats currently supported are XML, HTML and CSV. If an output format is not specified, the XML format will be the default format.

(2) Processing a directory location

java net.sf.saxon.Transform -l xslqual.xsl xslqual.xsl ruleset=rules.xml folder=location target=xml

The argument shown with green is a redundant input for this command. The source stylesheets are taken from the folder location, 'location'. The folder is searched recursively for XSLT files, with extension .xsl.

Rest of the command line options are same, as point (1).

A combined report is generated for all the input source files.

Following is a sample violation report produced by this tool (using the target=html option):

I suggest the rule priorities from 1 to 5, where 1 is a most severe violation and 5 is the least severe.

1. The tool is written in XSLT 2.0.
2. The tool uses certain Saxon specific extensions, so using Saxon is mandatory to use this tool. The basic version of Saxon will work for the current version of this tool.
3. The tool doesn't check for validity of the XSLT code (i.e., it doesn't attempt to compile it using an XSLT processor). The input code need only be a well-formed XML file, for using this tool.
4. Although I have tried my best to write rule XPath expressions with maximum accuracy, I do not take any warranty for the malfunctioning of the tool in any environment.
5. Any bug reports, and offer for help to improve this tool are most welcome.
6. The tool is completely open source, and anybody could use it for any purpose.
7. The default rules provided by the tool are my attempt to enhance XSLT code quality. Anybody is free to add their own rules in the ruleset file. I would appreciate suggestions from the community, to add any new rules.

Future directions:
1. We could group the results (violation reports) by some criteria (like, say the file name).
2. We could produce more contextual information in the violation reports. Like variable name, function name that are unused etc.
3. It would be good to partition the rules into various domains like performance, design, unused code etc. This could help in running a particular kind of check (like running only the performance rules), instead of running all the checks.
4. The utility currently doesn't analyze any dependant stylesheets via includes/imports. We could add this facility in the future.

I thank Michael Kay for answering few queries personally, which helped me to improve this tool.

Related links:

1. debugxslt    :


Last Updated: Jan 18, 2009