How to Generate an XSLT Transform Using Groovy StreamingMarkupBuilder
October 3rd, 2012
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?
thanks a lot, Alex. I was exactly looking for this code snippet!
You’re welcome Evgenia, glad you found it useful.
I am facing this error.
Error : can not resolve symbol ‘xsl’