Thursday, May 24, 2007

Advanced XSLT transformations with an development experiance

XSLT is a powerful Turing complete programing language, even though most of the developers do not use the powerful advanced features of XSLT. Which implies that, this blog entry is not going to be an introduction to XSLT.

Have you ever came across a situation where you have to do a common task for a group of XML nodes followed by the node specific tasks, using XSLT transformations? Yes I do...

I have done this when we are developing the WSO2-ESB administration console @ WSO2 which is an AJAX console to administer and monitor Apache Synapse and much more...

Here is our scenario

In WSO2-ESB/Synapse there is an element called "sequence" which is used to hold a set of "mediators" (mediators are the atomic components for message processing inside ESB/Synapse) bundled in to a single reference. Theses sequence definitions and all the other elements to configure ESB is fed to the system through the Synapse Configuration Language (XML based commanding language for Synapse). When we are trying to find a way to visually represent these sequences by keeping the following facts in mind, we have realized that the best fitter is XSLT.
  • It should be able to add another mediator visualization as extensions
  • It should be a maintainable code (XSLT or what ever...)
  • And most importantly, there should be a framework facilitating all the mediators with the common controls for tasks like move mediators up and down, delete them, add new one and so on. So that, adding new mediator visualization on top of this framework would add those controls to the new mediator as well keeping the main theme intact
Solution using XSLT and a little bit of JavaScript;
XML node of the sequence is something like the following, in this case which contains three mediators namely "log" followed by "send" followed by a "drop".

<syn:sequence name="testsequence" syn="http://ws.apache.org/ns/synapse">
<syn:log level="full" separator=","/>
<syn:send>
<syn:endpoint>
<syn:address uri="http://www.wso2.org/testservice"/>
</syn:endpoint>
</syn:send>
<syn:drop/>
</syn:sequence>


Using the "mode" and "priority" attributes of the "xsl:template" element we have come up with a design to solve this. The structure of the XSLT in the framework looks as follows.

  • mediator_view.xsl
    • xsl_includes.xsl
      • drop_view.xsl
      • log_view.xsl
      • send_view.xsl
By putting a common template match to get all the elements in to the mediator_view.xsl with a higher priority value, we were able to add the common controlling tasks to each and every element of the sequence qualified with Synapse namespace. Apart from adding these common controls for the mediators we have inserted a xsl:apply-templates tag selecting the current node, (Note that, if you do not specify the selection to the apply-templates, XSLT processor will consider the childnodes of the node current as the selection) and parsing the mode argument as "custom" to the apply-template. As you can see in the above structure, there are XSLTs for each and every mediator in which the mediator specific template match with the mode value set to "custom" with a lower priority exists, for the mediator specific visualizations. After all,in the mediator_view.xsl, we stated a normal xsl:apply-templates tag to recursively generate the mediator visualizations in the sequence.al xsl:apply-templates tag to recursively.

This is how our mediator_view.xsl looks like,

<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform" 
syn="http://ws.apache.org/ns/synapse">
<xsl:template match="syn:*" priority="0">
<!-- code for the common controls -->
<xsl:apply-templates select="." mode="custom"/>
</xsl:template>
</xsl:stylesheet>


This is a sample XSLT for a mediator specific visualization (in this case for the send mediator),

<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="syn:send" mode="custom" priority="2"
syn="http://ws.apache.org/ns/synapse">
<!-- code for the send mediator specific visualization -->
</xsl:template>
</xsl:stylesheet>


Here is how our visualization looks at the end of this processing,

0 comments: