{"id":1448,"date":"2012-01-26T09:42:29","date_gmt":"2012-01-26T08:42:29","guid":{"rendered":"http:\/\/www.pleus.net\/blog\/?p=1448"},"modified":"2012-01-26T09:42:29","modified_gmt":"2012-01-26T08:42:29","slug":"combining-groovy-and-xslt-for-data-transformation","status":"publish","type":"post","link":"https:\/\/www.pleus.net\/blog\/?p=1448","title":{"rendered":"Combining Groovy and XSLT for Data Transformation"},"content":{"rendered":"<p>In the blog post <a href=\"http:\/\/www.pleus.net\/blog\/?p=954\" traget=\"_blank\">Beautiful Transformations with Groovy<\/a> I described how easy it is to create data transformations with Groovy. But sometimes organisations invested massively in XSLT transformation and want to reuse their existing XSLT templates. Read on for an an example that shows how to do that.<\/p>\n<p>Assume we want to transform the following XML file to HTML:<\/p>\n<pre class=\"brush:xml\">\r\n<cars>\r\n  <car name='A6' make='Audi' year='2006'>\r\n    <country>Germany<\/country>\r\n    <description>Fast and nice<\/description>\r\n  <\/car>\r\n  <car name='Alhambra' make='Seat' year='1999'>\r\n    <country>Spain<\/country>\r\n    <description>Large and handy<\/description>\r\n  <\/car>\r\n  <car name='Punto' make='Fiat' year='1980'>\r\n    <country>Italy<\/country>\r\n    <description>Small and cheap<\/description>\r\n  <\/car>\r\n<\/cars>\r\n<\/pre>\n<p>Lets further assume the result should look like this:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/cars.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/cars.jpg\" alt=\"\" title=\"cars\" width=\"379\" height=\"144\" class=\"alignnone size-full wp-image-1480\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/cars.jpg 379w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/cars-300x113.jpg 300w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/cars-150x56.jpg 150w\" sizes=\"auto, (max-width: 379px) 100vw, 379px\" \/><\/a><\/p>\n<p>Does it make sense? I don&#8217;t know, but that&#8217;s not really important. \ud83d\ude09<\/p>\n<p>We have the following XSLT template to perform the transformation:<br \/>\n<a href=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template.jpg\" alt=\"\" title=\"template\" width=\"572\" height=\"453\" class=\"alignnone size-full wp-image-1505\" srcset=\"https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template.jpg 572w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template-300x237.jpg 300w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template-150x118.jpg 150w, https:\/\/www.pleus.net\/blog\/wp-content\/uploads\/2012\/01\/template-400x316.jpg 400w\" sizes=\"auto, (max-width: 572px) 100vw, 572px\" \/><\/a><\/p>\n<p>All you need is a Groovy script like the one below to  transform the xml file to html using the given xslt.<\/p>\n<pre class=\"brush:groovy\">\r\n\/\/ Load xslt\r\ndef xslt= new File(\"template.xsl\").getText()\r\n\r\n\/\/ Create transformer\r\ndef transformer = TransformerFactory.newInstance().newTransformer(new StreamSource(new StringReader(xslt)))\r\n\r\n\/\/ Load xml\r\ndef xml= new File(\"cars.xml\").getText()\r\n\r\n\/\/ Set output file\r\ndef html = new FileOutputStream(\"output.html\")\r\n\r\n\/\/ Perform transformation\r\ntransformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(html))\r\n<\/pre>\n<p>This is self-explanatory, isn&#8217;t it?<br \/>\nAs XSLT is somewhat limited when it comes to more complex transformations, it can be extended by custom processors which can we implemented in Java or Groovy. A custom processor in Groovy can be implemented like this:<\/p>\n<pre class=\"brush:groovy\">\r\npublic class AgeProcessor{\r\n    public def process(ExpressionContext context,int n){\r\n        return \"Age: \" + (2012 - n) + \" years\";\r\n    }\r\n}\r\n<\/pre>\n<p>The processor is hooked up to the XSLT using the expressions in line 3 and 28 of the above XSLT file.<br \/>\nThe examples above show how to reuse existing XSLT in Groovy. Are you interested to see the same same transformation in pure Groovy? (sorry, I could not resist ;-))<br \/>\nHere is the code:<\/p>\n<pre class=\"brush:groovy\">\r\n\/\/ Load xml\r\ndef cars = new XmlSlurper().parse(new File(\"cars.xml\"))\r\n\r\n\/\/ Set output file\r\ndef writer = new FileWriter(\"output.html\")\r\n\r\n\/\/ Perform transformation\r\ndef builder = new MarkupBuilder (writer);\r\nbuilder.html(xmlns:\"http:\/\/www.w3.org\/1999\/xhtml\") {\r\n    head {\r\n        title \"Cars collection\"\r\n    }\r\n    body {\r\n        h1(\"Cars\")\r\n        ul(){\r\n            cars.car.each{car ->\r\n                li(car.@name.toString() + \",\" + car.country + \",\" + car.description + \", Age: \" + (2012 - car.@year.toInteger()) + \" years\")\r\n            }\r\n        }\r\n    }\r\n }\r\n<\/pre>\n<p>It is shorter and self-contained. It is also more intuitive and therefore easier to maintain. But if you have the requirement to support XSLT in Groovy you now know how to do that.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the blog post Beautiful Transformations with Groovy I described how easy it is to create data transformations with Groovy. But sometimes organisations invested massively in XSLT transformation and want to reuse their existing XSLT templates. Read on for an an example that shows how to do that. Assume we want to transform the following &hellip; <a href=\"https:\/\/www.pleus.net\/blog\/?p=1448\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Combining Groovy and XSLT for Data Transformation<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,3],"tags":[17,11],"class_list":["post-1448","post","type-post","status-publish","format-standard","hentry","category-bpm","category-soa","tag-esb","tag-groovy"],"_links":{"self":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1448"}],"version-history":[{"count":82,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1448\/revisions"}],"predecessor-version":[{"id":1588,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1448\/revisions\/1588"}],"wp:attachment":[{"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pleus.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}