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.


XSLT commands like template and value-of are defined in the “” 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: "")
    xsl.stylesheet(version:"2.0") {
        xsl.template(match:"/") {
            html {
                head {
                    title("list of items")
            body {
                h1("items") {
                   ul {
        xsl.template(match:"item") {
            li {

And here’s the XSLT the script above generates:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="" version="2.0">
    <xsl:template match="/">
                <title>list of items</title>
                    <xsl:apply-templates select="items/item"/>
    <xsl:template match="item">
            <xsl:value-of select="name"/>

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’