/ Development  

Prepare the magic; Watch how XML data gets a mind-blowing makeover with XSLT

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

When you connect with people you start to see and hear things at a higher level! This time a high-valuable feature I would never have found if it wasn’t for my comrade in crime (the godfather of BPM…you know who you are!); This person noted me about the greatest of all webservices. Yes, you’ll be amazed what would be possible after the reading of this blog post. It all has to do with the transformation of data before you expose it any further. For our platform, this data will be in XML format and when you know a bit of eXtensible Stylesheet Language Transformations, the world is open for any complex transformation skills!

During this introduction, I also spotted an old friend on the interwebs…“The Apache FOP Project”. It’s not for this post, but I put it on my backlog; Spitting out PDFs based on XML data is a user story in every project! 😏 Why using complex products when you can do it with a couple of coding-lines and standardization on stylesheets!


Let get right into it…

For my journey I start simple with a basic XML file in my good old Notepad++ with the enablement of the XML Tools plugin. My second file is this XSLT file to make a conversion on the XML. Both files are open in my Notepad++; Now move to the ‘Plugins’ action in the top bar and open the ‘XML Tools’. You see a long list of actions where ‘Pretty print’ is a common action to do, but I would like to move to the action ‘XSL Transformation’:

xslt_001

Make sure you have the XML file in view as this action uses it as input.

Now, select the XSL file and hit the ‘Transform’ button to see the outcome…It’s magic! 🔮 From one XML to another XML; You can even product an HTML page with this technique, but that’s not the point of this post…Just that you know!

I already have some basic XSLT knowledge; If you don’t have it, here are some resources to start:

The next question would be: How can we use this transformation skill in our beloved AppWorks platform? Well, as AppWorks is service oriented and XML minded, it would be impossible not to have a service available that answers our question…And there is! With the fancy name XSLtransformGeneric living in the namespace http://schemas.cordys.com/datatransform/4.2

AHA! Let’s have a look in the ‘Web Service Interface Explorer’ artifact:

xslt_002

Where are you waiting for…Right-click it and do a first test request. The input? Yes, my friend…As you wish (The XML- and XSL-parts are from the files at the start of this post!):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<XSLtransformGeneric xmlns="http://schemas.cordys.com/datatransform/4.2">
<SourceDoc>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Dolly Parton</artist>
<country>USA</country>
<company>RCA</company>
<price>9.90</price>
<year>1982</year>
</cd>
</catalog>
</SourceDoc>
<StyleSheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<output>
<header>My CD Collection</header>
<xsl:apply-templates select="catalog"/>
</output>
</xsl:template>
<!-- for each CD in selected catalog apply this template! -->
<xsl:template match="cd">
<cd-info>
<cd-title>
<xsl:value-of select="title"/>
</cd-title>
<cd-artist>
<xsl:value-of select="artist"/>
</cd-artist>
</cd-info>
</xsl:template>
</xsl:stylesheet>
</StyleSheet>
</XSLtransformGeneric>
</SOAP:Body>
</SOAP:Envelope>

This is the output as a result on this service call:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<data>
<XSLtransformGenericResponse xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.cordys.com/datatransform/4.2">
<tuple>
<output>
<header>My CD Collection</header>
<cd-info>
<cd-title>Empire Burlesque</cd-title>
<cd-artist>Bob Dylan</cd-artist>
</cd-info>
<cd-info>
<cd-title>Hide your heart</cd-title>
<cd-artist>Bonnie Tyler</cd-artist>
</cd-info>
<cd-info>
<cd-title>Greatest Hits</cd-title>
<cd-artist>Dolly Parton</cd-artist>
</cd-info>
</output>
</tuple>
</XSLtransformGenericResponse>
</data>

Isn’t that a beauty of a service!? Also, nicely in ‘Pretty print’ format…That’s exactly why we love AppWorks…The “App” just “works”! 🤗
Now that we know the service call, it’s easy to use it in any future BPM, for any XML transformation required. Let’s go through some open questions from my side…


Q/A

Is XSLT 2.0 supported?

Well, partly!?!? Yes, you read it correctly and I also find it strange as this XSLT 2.0 function is NOT working: <xsl:value-of select="current-date()"/>. Guess what; This XSLT 2.0 function is working fine: <xsl:value-of select="upper-case('hello world')"/>…That’s from my service call in AppWorks (not Notepad++)! Even with the stylesheet version still at 1.0…”Stranger Things”! I’m not diving into this, but from what I understand “2.0” relates to XSLT 2.0, but also xPath 2.0 and maybe AppWorks does something under the hood!? Any comment is welcome…

Is there a faster way to build XSLT?

Yes, I can remember a tool from long ago called Oxygen; Not free, but works great. I see Visual Studio Code has no direct way to do this trick; You could use a plugin! I saw also another tool from the past named Cooktop…It’s just memories; Don’t use it as it’s not developed anymore. Notepad++ is already shown!
See if the tool supports “debugging”…You eventually need it, but that’s just my experience! 😁 For a quick XSLT assessment use this.

Do we need this good old stuff in our XSLT document?

1
2
3
4
5
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" xalan:indent-amount="2"/>
...
</xsl:stylesheet>

Nope, as our beloved platform already makes it a “pretty print” in the response; You can use it in your external editor to pretty print the output!

What about theses weird statements?

1
2
3
<xsl:template match="/|@*|node()">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>

Well, have a read here

How about a for-loop with xsl:for-each?

1
2
3
4
5
6
7
8
9
10
<xsl:for-each select="catalog/cd">
<cd-info>
<cd-title>
<xsl:value-of select="title"/>
</cd-title>
<cd-artist>
<xsl:value-of select="artist"/>
</cd-artist>
</cd-info>
</xsl:for-each>

Or what about calling a template (or method/function): xsl:call-template?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<output>
<header>My CD Collection</header>
<xsl:for-each select="catalog/cd">
<xsl:call-template name="cd-info">
<!-- It's even possible to pass parameters
in the template call with 'xsl:with-param'! -->
</xsl:call-template>
</xsl:for-each>
</output>
</xsl:template>
<xsl:template name="cd-info">
<cd-info>
<cd-title>
<xsl:value-of select="title"/>
</cd-title>
<cd-artist>
<xsl:value-of select="artist"/>
</cd-artist>
</cd-info>
</xsl:template>
</xsl:stylesheet>

Or even better…do a xsl:sort!?

1
2
3
4
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist" order="descending"/>
<xsl:call-template name="cd-info"/>
</xsl:for-each>

There is sooooo much more to explore here, but that’s a task for you to experience…I’m just giving you a heads-up on your creativity! 🤠


That’s our “DONE” for this post. A high-valuable skill is shared with this post and the world is at your feed when it comes to XML transformation using the techniques behind XSLT. I definitely see a use-case in any AppWorks project for the XSLtransformGeneric webservice shared in this post…Now it’s up to you how you use it. As with everything…”Great power comes with great responsibility”, so be thinkable on the implementations and keep things simple. Have a great transformation weekend, and I will see you next week with on another interesting AppWorks Tips topic! 😉

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?