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">
<message>
Avoid using the operator // near the
root of a large tree
</message>
<xpath>
//(@match | @select)[starts-with(.,
'//')]
</xpath>
<priority>2</priority>
<example>
<!-- VIOLATION -->
<xsl:variable name="x"
select="//x/y/z" />
<!-- REPAIR -->
<xsl:variable name="x"
select="/a/b/x/y/z" />
</example>
</rule>
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.
Notes:
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.
Acknowledgements:
I thank Michael Kay for answering few
queries personally, which helped me to improve this tool.
Related links:
1. debugxslt :
http://code.google.com/p/debugxslt/
Last Updated: Jan 18, 2009