Groovy and XSLT are two great options for working with XML. While both have their uses, I was curious about combining them to generate an XSLT transform with a Groovy script. It turns out that doing this is pretty straight forward, with a couple of minor caveats.

Namespaces

XSLT commands like template and value-of are defined in the “http://www.w3.org/1999/XSL/Transform” namespace (commonly aliased with xsl). Therefore, generating XML with XSLT commands requires using a namespace.

Luckily, Groovy’s StreamingMarkupBuilder has support for namespaces via a special markup object called mkp, which contains declareNamespace() function:

def xmlWithNamespace = new StreamingMarkupBuilder().bind {
    mkp.declareNamespace(abc: "some namespace")
}

Once declared, creating an node using the namespace is simply a matter of using the “.” notation:

namespace.nodeName {
    namespace.anotherNodeName {
        ...
    }
} 

Unfriendly Casing Style

Like most other W3C standards, XSLT uses “lower-case-with-hyphens” casing style for its keywords: value-of, apply-templates, and so on. This creates a slight complication for Groovy because words with hyphens are not valid symbols (i.e. xsl.value-of{} won’t work). Instead, you have to surround these terms in quotes: xsl."value-of"{}.

Final Result

So, here’s a Groovy script to generate a simple XSLT transform:

def xmlWithNamespace = new StreamingMarkupBuilder().bind {
    mkp.declareNamespace(mynamespace: "http://www.w3.org/1999/XSL/Transform")
}
    xsl.stylesheet(version:"2.0") {
        xsl.template(match:"/") {
            html {
                head {
                    title("list of items")
                }
            }
            body {
                h1("items") {
                   ul {
                       xsl."apply-templates"(select:"items/item")
                   }
                }
            }
        }
        xsl.template(match:"item") {
            li {
                xsl."value-of"(select:"name")
            }
        }
    }
}

And here’s the XSLT the script above generates:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <html>
            <head>
                <title>list of items</title>
            </head>
        </html>
        <body>
            <h1>
                <ul>
                    <xsl:apply-templates select="items/item"/>
                </ul>
            </h1>
        </body>
    </xsl:template>
    <xsl:template match="item">
        <li>
            <xsl:value-of select="name"/>
        </li>
    </xsl:template>
</xsl:stylesheet>

You may also like:

tagged with:

Did you love / hate / were unmoved by this post?
Then show your support / disgust / indifference by following me on Twitter!

This post got 3 comments so far. Care to add yours?

  1. Evgenia says:

    thanks a lot, Alex. I was exactly looking for this code snippet!

  2. Adeel says:

    I am facing this error.

    Error : can not resolve symbol ‘xsl’

Leave a Reply