[Header Graphic]

XSLT Explorer

Table of Contents

XSLT Explorer is an XSLT stylesheet that performs a small amount of static analysis on an XSLT stylesheet and publishes the results in HTML. The idea is that it gives you an overview of the structure of your stylesheet.

Explorer identifies templates, functions, and variables within each module. It attempts to show you any that are unused, shadowing other globals, or are used only once in another module.

Output

The output from the explorer is a web page. Here’s an example (from test.xsl in the test suite):

[Screen capture]

This screen shot shows one parameter, one variable, and two templates. Each section shows relevant properties about the declaration: names, types, modes, etc., what other declarations refer to it, and what declarations it references. Each of the references is a link to the referent.

If line numbers were enabled, § is a link to the declaration in the source. If a template or function is recursive, that’s indicated by ♻︎. Three noteworthy conditions are identified:

Points out declarations that are unused.
⚠︎
Points out (global) declarations that shadow earlier ones.
☝︎
Points out declarations that are declared in one module but used exclusively only in one other module. (Candidates to be moved, perhaps?)

In match templates, the match is indicated as ≅ a list of elements. The match attempts to capture the list of elements involved, but all predicates are stripped away. (The explorer can’t practically make use of them, and removing them simplifies the display.)

Starting in version 0.1.6, comments containing the string “FIXME:” are also highlighted.

An interactive example of the explorer run on itself is online at https://xslt.xmlexplorer.com/ouroboros/.

Getting the explorer

You can download the latest release from the GitHub project. Alternatively, you can clone or fork the project and build it yourself. Share and enjoy!

Using the explorer

  1. Download the distribution and unpack it somewhere.
  2. Transform your stylesheet with xslt/explorer.xsl.
  3. Point your browser at the output! If you put the output in the same directory where you unpacked the distribution, it’ll just work. If you want to put it somewhere else, copy the CSS and JS directories appropriately.

If you are using Saxon PE or EE, use the `-l` (lowercase “L”) option to include line numbers.

Parameters

The following parameters control aspects of the output:

source-listings
If “false”, the source code listings will not be included. (Default=“true”)
format
The usual output format is an HTML page. Select “data” for a plain XML summary of the results. (Default=“html”)

In addition, there are some debugging flags:

debug-parse
If not empty, the intermediate parser output will be stored there.
debug-resolve
If not empty, the intermediate resolved output will be stored there.
debug-analyze
If not empty, the intermediate analyzed output will be stored there.
xspec-tests
If “true”, a few small tweaks are made to the results so that irrelevant differences between the dev environment and the CI environment don’t cause spurious test failures. (Default=“false”)

Caveats

  1. See the issues list.
  2. The trick where it links from the instruction to the source code depends on having the CSS configured so that the line numbers align with the lines in the Prism listing.
  3. The output isn’t especially accessible. A more accessible transformation of the “data” output should be possible.

How it works

XSLT is perfectly capable of analyzing the XML structure of your stylesheet. To extract information from XPath expressions, it uses an XPath 3.1 parser generated by Gunther Rademacher’s always excellent REx Parser Generator.

One consequence of doing the XPath parsing in XSLT is that very, very large XPath expressions may have quite poor performance. To attempt to workaround this, a primitive test is made first: if an expression does not contain any “(“ or “$” characters, then it can’t contain any function calls or variable references.

The XPath 3.1 parser contains a 60K XPath expression that brings the parser to its knees. This quick check avoids that expression. If you want to avoid parsing a module entirely, stick <?xsltexplorer-skip-import?> immediately in front of the import statement (or <?xsltexplorer-skip-include?> in front of an include statement).

With the XPath parsing sorted, the code takes a multi-pass approach:

  1. Parse the structure, loading imports and includes into a flat structure.
  2. Parse that structure to identify function calls, template calls, and variable references.
  3. For those references, work out what actual instruction they refer to, taking into consideration the possibility of shadowing.
  4. Extract the details of the analysis into a simple XML document.
  5. Transform that document into HTML.