Click here to Skip to main content
Click here to Skip to main content

XML Processing using XSL with Parameters

, 28 Mar 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Passing Parameters to XSL

Introduction 

Recently during the development of a consolidated report for a web application we used XML/XSL processing to generate the report which is basically a custom grid generated out of the XSL processing. The screenshot of the user interface is given in the overview section.

The report was designed using a custom grid generated using the XSL from the XML data. The report was basically showing consolidated data for daily, MTD and yearly. The XML output contains data for daily, MTD and YTD for a given trade date. So the problem was extracting the corresponding data from the XML when the user selects Daily /MTD/Yearly in the UI. 

As usual the initial thoughts were to use three XSL for processing daily, monthly & yearly. But when looking forward, thoughts about maintainability and repetition of the code made me to look for a more reliable solution. Let’s see how we implemented the solution.

Overview

Not going into the details of how the grid was developed; just adhering to the problem lets look at the brief of the requirements.

To make the understanding much better lets have a glance of the reporting screen. The user selects the report type (value will be either ‘D’,’Y’,’M’) from the screen and click the apply button; on the basis the user selection the XML data need to be extracted and processed.

For e.g. In the report screen the report header is one of the XML element which needs to be extracted corresponding to the report type selected by the user. When the user selects ‘Daily’ from the report type then XSL processor needs to extract the XPATH ‘root/reportparameters/reportdescription/description/@view’ = ‘D’ from the XML. 

XML Sample

Please find the sample XML below. The solution needs to extract the XML data from the nodes for attribute value like ‘view’ from ‘root/reportparameters/reportdescription/description/@view’ for report header corresponding to the report type.

The attribute have values like ‘D’, ‘M’, ‘Y’ which corresponds to daily, MTD, yearly respectively.

Similarly for the report data, this needs to be from ‘root/datarows/datarow/amounts/@aggregation’. 

Solution 1

The easiest solution is to have three XSL where the attribute value ‘D’,’M’,’Y’ is hard coded. But on long run this becomes question for maintainability and the same code is repeated over the three XSL. The snippet of one of the three XSL is given below. The XML/XSL processing technique is explained in the solution 2.

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
 
<div class="controlname reportdesc" style="font-style: italic">
<xsl:for-each select ="root/reportparameters/reportdescription">
<xsl:value-of select="description[@view='D']"/>
</xsl:for-each>
</div> 
 
<br/>
</xsl:template>
</xsl:stylesheet>

Solution 2

The best solution is to have a single XSL where parameter can be passed from web application which can be done from client side or server side depending on the requirement. The challenge will be how we can pass parameter to XSL from client side processing and whether the same can be done from server side too?

Will explain both the ways as we go.

Let’s quickly jump to the solution, not sure whether I have explained a lot rather than coming to the solution.

XML/XSL processing from Client Side

The XSL processing is done by creating Microsoft.XMLDOM object to load the XML data. Similarly object to load XSLT need to be created from FreeThreadedDOMDocument. The transformation is done on the XSLT processor object created; this is done by calling the transform method on the above object.

The above process is preferred over the one where we can use "transformNode" method of Microsoft.XMLDOM object to process the XML since this one doesn’t allows to parameters in XSLT.

The steps involved are:

1. var xml = new ActiveXObject("Microsoft.XMLDOM"); 
2. var xslt = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
3. xml.load("data.xml");
4. xslt.load("transformxsl.xsl");
5. var processor = new ActiveXObject("Msxml2.XSLTemplate");
6. processor.stylesheet = xslt;
7. var objXSLTProc = processor.createProcessor();
8. objXSLTProc.input = xml;
9. objXSLTProc.addParameter("reporttype", GetReportType());
10. objXSLTProc.transform();
11. document.getElementById("divReportGrid").innerHTML = objXSLTProc.output;

In the above code line # 3 does the loading of the XML; this can be done also by using a call to a separate ASPX page where response type is ‘text/xml’.

Line # 9 does the actual parameter passing; the objXSLTProc object is defined with a parameter name ‘reporttype’. The value of the same is retrieved using the JavaScript function GetReportType().

Finally the report is rendered using the XSL processor output to a DIV tag.

Let’s have a look of the XSL (For explanation it’s a sample from the original XML)

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name ="reporttype"></xsl:param>

<xsl:template match="/">
<div class="controlname reportdesc" style="font-style: italic">
<xsl:for-each select ="root/reportparameters/reportdescription">
<xsl:value-of select="description[@view=$reporttype]"/>
</xsl:for-each>
</div> 
<br/>
</xsl:template>
</xsl:stylesheet>

In the above XSL a XSL param named ‘reporttype’ is defined. And the report header is processed using the XPATH for the attribute ‘view’ which is linked to the XSL param defined.

XML/XSL Processing from Server Side (C#)

The XML/XSL processing is done using the XPathDocument and applying parameter on the XsltArgumentList object. Finally the same is transformed on the XPathDocument object using the XslCompiledTransform object. After XSL processing the HTML output will be in the StringWriter object.

MemoryStream ms = 
   new MemoryStream(System.Text.Encoding.UTF8.GetBytes(//Get the XML for processing));
XPathDocument document = new XPathDocument(ms);
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(Server.MapPath(@"/XSL/Sample.xsl"));
StringWriter sw = new StringWriter();
XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("reporttype", "", reportTypeParam.ToString());

transform.Transform(document, xslArg, sw);

Solution Implementation

Finally the solution applied was client side XSL processing using a single XSL. The server side XML/XSL processing was applied for generating an Excel report.

Summary

In the article I tried to explain various ways by which XML/XSL processing with parameter passing can be done and applied to various applications.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Anish_R
Technical Lead
India India
No Biography provided
Follow on   Google+

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 28 Mar 2012
Article Copyright 2012 by Anish_R
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid