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:

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’