ANN: Announcing XSLT Lint

I am pleased to announce XSLT Lint -- a tool for performing static code analysis of XSLT.

Idea of the project is to unscramble poorly coded XSLT, and patch the code accurately, so changes can be viewed nicely displayed line-by-line in file comparison tool.

XSLT is also an XML, which makes it consumable by another XSLT, i.e. XSLT is analyzing XSLT. The big difference is that XSLT Lint is also fixing problematic code.

The other words, source XSLT is modified not as XML, but as text, so formatting is not lost, so line diff is minimal. For example:

<element attr1="value1"
    attr2="value2">
<xsl:attribute name="attr3">value3</xsl:attribute>
</element>

will be transformed as:

<element attr1="value1"
    attr2="value2" attr3="value3"/>

Notice line break between attr1 and attr2 is not lost: if XSLT lint would work by serializing XSLT as XML, line break would be lost so line diff would become distorted.

The result of these efforts is a GUI program that let user select folder w/ source XSLT, select refactorings to apply and view resulting line diff.

XSLT Lint Refactorings

These are refactorings that XSLT Lint applies to XML 1.0 code:

  • merge closing tag (strict)
    This refactoring merges consecutive opening and closing tags.

    old code:

    a<element></element>b

    new code:

    a<element/>b
  • merge closing tag (lax)
    This refactoring merges non-consecutive opening and closing tags, ignoring whitespace but not comments.

    old code:

    a<element>  </element>b

    new code:

    a<element/>b

These are refactorings that XSLT Lint applies to XSLT 1.0 code:

  • inline xsl:element
    This refactoring changes excessively verbose xsl:element to directly coded XML.

    old code:

    <xsl:element name="elementName">
        ...
    </xsl:element>

    new code:

    <elementName>
        ...
    </elementName>
  • inline xsl:attribute/text()
    This refactoring changes excessively verbose xsl:attribute to directly coded XML.

    old code:

    <elementName>
        <xsl:attribute name="attrName">value</xsl:attribute>
        ...
    </elementName>

    new code:

    <elementName attrName="value">
        ...
    </elementName>
  • inline xsl:variable/xsl:value-of
    This refactoring changes xsl:variable w/ single xsl:value-of to shorter form.

    old code:

    <xsl:variable name="varName">
        <xsl:value-of select="xpath"/>
    </xsl:variable>

    new code:

    <xsl:variable name="varName" select="xpath"/>
  • inline xsl:param/xsl:value-of
    This refactoring changes xsl:param w/ single xsl:value-of to shorter form.

    old code:

    <xsl:param name="paramName">
        <xsl:value-of select="xpath"/>
    </xsl:param>

    new code:

    <xsl:param name="paramName" select="xpath"/>
  • inline xsl:with-param/xsl:value-of
    This refactoring changes xsl:with-param w/ single xsl:value-of to shorter form.

    old code:

    <xsl:with-param name="paramName">
        <xsl:value-of select="xpath"/>
    </xsl:with-param>

    new code:

    <xsl:with-param name="paramName" select="xpath"/>

These are refactorings that XSLT Lint applies to XSLT 2.0 code:

  • inline xsl:attribute/xsl:value-of
    This refactoring changes xsl:attribute w/ single xsl:value-of to shorter form.

    old code:

    <xsl:attribute name="attrName">
        <xsl:value-of select="xpath"/>
    </xsl:attribute>

    new code:

    <xsl:attribute name="attrName" select="xpath"/>
  • inline xsl:message/xsl:value-of
    This refactoring changes xsl:message w/ single xsl:value-of to shorter form.

    old code:

    <xsl:message terminate="yes">
        <xsl:value-of select="xpath"/>
    </xsl:message>

    new code:

    <xsl:message terminate="yes" select="xpath"/>
  • merge xsl:for-each/xsl:apply-templates
    This refactoring changes xsl:for-each w/ single xsl:apply-templates to single xsl:apply-templates.

    old code:

    <xsl:for-each select="xpath1">
        <xsl:apply-templates select="xpath2"/>
    </xsl:for-each>

    new code:

    <xsl:apply-templates select="xpath1/xpath2"/>
  • merge consecutive xsl:apply-templates
    This refactoring merges consecutive xsl:apply-templates to single xsl:apply-templates.

    old code:

    <xsl:apply-templates select="xpath1"/>
    <xsl:apply-templates select="xpath2"/>

    new code:

    <xsl:apply-templates select="xpath1,xpath2"/>

Manual on XSLT Lint GUI

Screenshot of XSLT Lint GUI

  1. Pick a refactoring — select the refactoring you want to apply
  2. Synopsis — displays an example of how code will look "before" and "after"
  3. Source Folder — select original XSLT file or folder
  4. Target Folder — select file or folder where to place patched file (original XSLT will not be modified)
  5. Transform — run the transform
  6. Changes — displays files that were modified, and Unix diff patch that is generated by comparing original and transformed file. Note: Windows users can install Unix diff util from http://gnuwin32.sourceforge.net/packages/diffutils.htm

XSLT Lint can be launched online: http://www.gerixsoft.com/sites/gerixsoft.com/files/xslt-lint/xslt-lint.jnlp. Note: This is Java webstart application, you must have Java installed on your computer to run XSLT Lint. The message (NOT VERIFIED) Andriy Gerasika that you will see is OK, since I was using self-signed certificate.

I am very interested in feedback about:

  1. refactorings already implemented -- are they correct?
  2. suggestions for future refactorings, people's experience dealing w/ poorly coded XSLT

Comments

It's too bad that it's not open source

Related to this,
it's not nice to be obliged to run a self-signed application.

And , yes , it's a nice tool, although it would be nice to separate the safe rules and the others.

Post new comment

The content of this field is kept private and will not be shown publicly.