XSLT Programming

XSLT = XSL Transformations

XSLT is the most important part of XSL. XSL stands for EXtensible Stylesheet Language.

XSLT is used to transform an XML document into another XML document, or another type of document that is recognized by a browser, like HTML and XHTML. Normally XSLT does this by transforming each XML element into an (X)HTML element.

With XSLT you can add/remove elements and attributes to or from the output file. You can also rearrange and sort elements, perform tests and make decisions about which elements to hide and display, and a lot more.

A common way to describe the transformation process is to say that XSLT transforms an XML source-tree into an XML result-tree.

XSLT uses XPATH for navigating and searching inside an XML file. XPath is a language for finding information in an XML document. XPath is used to navigate through elements and attributes in an XML document.

For starting with XSLT programming, you need to know XPATH fundamentals. I will go through XPATH fundamentals briefly and then I will explain XSLT programming.

XPATH Fundamentals:

Sample XML file:


<LOB NAME="FUSION" Id="1">
<ISSUE_TYPE NAME="Techstack Issues" Id="1">
<QUESTION TYPE="TEXT" MANDATORY="FALSE" READONLY="FALSE" DEPENDENT_ON="NULL" PARENT="NULL" VALUE="e.g. Oracle RDBMS 10.2.0.2.0" DEPENDENT_VALUE="NULL" DISPLAY="Version/Drop of Techkstack" ID="3" NAME="it_ver" SIZE="50" ISCOMMON="TRUE" />
<QUESTION TYPE="LOV" MANDATORY="TRUE" READONLY="FALSE" DEPENDENT_ON="NULL" PARENT="TRUE" VALUE="NULL" ISCOMMON="TRUE" DEPENDENT_VALUE="NULL" DISPLAY="Is this a documentation bug?" ID="4" NAME="it_isdocbug" SIZE="2">
<OPTION SELECTED="FALSE" DISPLAY="YES" ID="YES" VALUE="YES" />
<OPTION SELECTED="FALSE" DISPLAY="NO" ID="NO" VALUE="NO" />
</QUESTION>
<QUESTION TYPE="TEXT" MANDATORY="TRUE" READONLY="FALSE" DEPENDENT_ON="it_isdocbug" PARENT="NULL" VALUE="NULL" DEPENDENT_VALUE="NO" DISPLAY="Please provide a minimal standalone reproducible testcase" ID="5" NAME="it_testcase" SIZE="1000" ISCOMMON="TRUE" />
<QUESTION TYPE="LOV" MANDATORY="TRUE" READONLY="FALSE" DEPENDENT_ON="it_isdocbug" PARENT="TRUE" VALUE="NULL" ISCOMMON="TRUE" DEPENDENT_VALUE="YES" DISPLAY="Doc bug is related to?" ID="6" NAME="it_docbugto" SIZE="2">
<OPTION SELECTED="FALSE" DISPLAY="Online Help" ID="ONLINE" VALUE="ONLINE" />
<OPTION SELECTED="FALSE" DISPLAY="Developement Guide" ID="DEVGUIDE" VALUE="DEVGUIDE" />
<OPTION SELECTED="FALSE" DISPLAY="Other" ID="OTHER" VALUE="OTHER" />
</QUESTION>
<ISSUE_SUB_TYPE NAME="Oracle RDBMS" Id="1">
<BUG_PROD_ID VALUE="5" />
<BUG_DB_COMP VALUE="RDBMS" />
<BUG_DB_SUBCOMP VALUE="NULL" />
<QUESTION TYPE="TEXT" MANDATORY="TRUE" READONLY="FALSE" DEPENDENT_ON="it_isdocbug" PARENT="NULL" VALUE="NULL" ISCOMMON="FALSE" DEPENDENT_VALUE="NO" DISPLAY="Please provide trace files/Stack trace if applicable" ID="1" NAME="ist_q1" SIZE="1000" />
</ISSUE_SUB_TYPE>
<ISSUE_SUB_TYPE NAME="Oracle Middleware Extension" Id="2">
<BUG_PROD_ID VALUE="2314" />
<BUG_DB_COMP VALUE="NULL" />
<BUG_DB_SUBCOMP VALUE="NULL" />
</ISSUE_SUB_TYPE>
<ISSUE_SUB_TYPE Id="3" NAME="BPEL">
<BUG_PROD_ID VALUE="1669" />
<BUG_DB_COMP VALUE="NULL" />
<BUG_DB_SUBCOMP VALUE="NULL" />
</ISSUE_SUB_TYPE>
</ISSUE_TYPE>
</LOB>


XSLT Syntax:

Expression Description
nodename Selects all child nodes of the named node
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
. Selects the current node
.. Selects the parent of the current node
@ Selects attributes

Examples:

To reach to NAME attribute of ISSUE_TYPE element we can use following command

LOB/ISSUE_TYPE/@NAME. Similarly we can use the following commands as well

Path Expression Result
/LOB/ISSUE_TYPE/ISSUE_SUB_TYPE[0] Selects the first ISSUE_SUB_TYPE element that is the child of the ISSUE_TYPE element.
Note: IE5 and later has implemented that [0] should be the first node, but according to the W3C standard it should have been [1]!!
/LOB/ISSUE_TYPE/ISSUE_SUB_TYPE[last()] Selects the last ISSUE_SUB_TYPE element that is the child of the ISSUE_TYPE element
/LOB/ISSUE_TYPE/ISSUE_SUB_TYPE[last()-1] Selects the last but one ISSUE_SUB_TYPE element that is the child of the ISSUE_TYPE element
/LOB/ISSUE_TYPE/ISSUE_SUB_TYPE[position()<3] Selects the first two ISSUE_SUB_TYPE elements that are children of the ISSUE_TYPE element
//ISSUE_TYPE[@NAME] Selects all the ISSUE_TYPE elements that have an attribute named NAME
//ISSUE_SUB_TYPE[@NAME=’BPEL’] Selects all the ISSUE_SUB_TYPE elements that have an attribute named NAME with a value of ‘BPEL’
/ISSUE_TYPE/ISSUE_SUB_TYPE[@ID=3] Selects all the ISSUE_SUB_TYPE elements of the ISSUE_TYPE element that have a ID attribute with a value equal to 3

Wildcard Description
* Matches any element node
@* Matches any attribute node
node() Matches any node of any kind

For more information on XPATH syntax and examples check XPATH Tutorial

XSLT programing:

The above XML can be transformed into HTML as given below. Please note the columns and the values and compare it will XML elements. We can vary the columns based on our requirements.

14.jpg

The code for the same is as given below.

===============================================================


<font color="#999999"><?xml version="1.0" encoding="iso-8859-1"?>
<!-- DWXMLSource="test.xml" -->
&lt;!DOCTYPE xsl:stylesheet  [
<!ENTITY nbsp   " ">
<!ENTITY copy   "©">
<!ENTITY reg    "®">
<!ENTITY trade  """>
<!ENTITY mdash  "">
<!ENTITY ldquo  "">
<!ENTITY rdquo  "">
<!ENTITY pound  "£">
<!ENTITY yen    "¥">
<!ENTITY euro   "¬">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="iso-8859-1" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="LOB">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Untitled Document</title>
</head>
<body>
<table border="1"  cellpadding="2" cellspacing="0" width="100%">
<tr>
<td align="center"><b>Issue Type</b></td>
<td align="center"><b>Sub Issue Type</b></td>
<td align="center"><b>Question</b></td>
<td align="center"><b>Mandatory</b></td>
<td align="center"><b>Field</b></td>
<td align="center"><b>Question ID</b></td>
<td align="center"><b>Question Name</b></td>
<td align="center"><b>Dependent On</b></td>
<td align="center"><b>Dependent Value</b></td>
</tr>
<xsl:for-each select="ISSUE_TYPE/QUESTION">
<tr>
<td><xsl:value-of select="../@NAME"/></td>
<td></td>
<td><xsl:value-of select="@DISPLAY"/></td>
<xsl:if test="@MANDATORY='TRUE'">
<td>Yes</td>
</xsl:if>
<xsl:if test="@MANDATORY='FALSE'">
<td>No</td>
</xsl:if>
<td><xsl:if test="@READONLY='TRUE' and @TYPE != 'LOV'">
<input type="{@TYPE}" readonly="{@READONLY}" id="{@ID}" name="{@NAME}" size="28" value="{@VALUE}"/>
</xsl:if>
<xsl:if test="@READONLY='FALSE' and @TYPE != 'LOV'">
<input type="{@TYPE}" id="{@ID}" name="{@NAME}" size="28" value="{@VALUE}"/>
</xsl:if>
<xsl:if test="@TYPE='LOV'">
<select id="@ID" name="@NAME">
<xsl:for-each select="OPTION">
<option value="@VALUE" id="@ID"><xsl:value-of select="@DISPLAY"/></option>
</xsl:for-each>
</select>
</xsl:if>
</td>
<td><xsl:value-of select="@ID"/> </td>
<td><xsl:value-of select="@NAME"/> </td>
<xsl:if test="@DEPENDENT_ON != 'NULL'">
<xsl:variable name="dependent_on" select="@DEPENDENT_ON"/>
<xsl:for-each select="/LOB/ISSUE_TYPE/QUESTION">
<xsl:if test="@NAME=$dependent_on">
<td><xsl:value-of select="@DISPLAY"/></td>
</xsl:if>
</xsl:for-each>
<td><xsl:value-of select="@DEPENDENT_VALUE"/></td>
</xsl:if>
<xsl:if test="@DEPENDENT_ON = 'NULL'">
<td><xsl:value-of select="@DEPENDENT_ON"/></td>
<td><xsl:value-of select="@DEPENDENT_VALUE"/></td>
</xsl:if>
</tr>
</xsl:for-each>
<xsl:for-each select="ISSUE_TYPE/ISSUE_SUB_TYPE/QUESTION">
<tr>
<td><xsl:value-of select="../../@NAME"/></td>
<td><xsl:value-of select="../@NAME"/></td>
<td><xsl:value-of select="@DISPLAY"/></td>
<xsl:if test="@MANDATORY='TRUE'">
<td>Yes</td>
</xsl:if>
<xsl:if test="@MANDATORY='FALSE'">
<td>No</td>
</xsl:if>
<td><xsl:if test="@READONLY='TRUE' and @TYPE != 'LOV'">
<input type="{@TYPE}" readonly="{@READONLY}" id="{@ID}" name="{@NAME}" size="28" value="{@VALUE}"/>
</xsl:if>
<xsl:if test="@READONLY='FALSE' and @TYPE != 'LOV'">
<input type="{@TYPE}" id="{@ID}" name="{@NAME}" size="28" value="{@VALUE}"/>
</xsl:if>
<xsl:if test="@TYPE='LOV'">
<select id="@ID" name="@NAME">
<xsl:for-each select="OPTION">
<option value="@VALUE" id="@ID"><xsl:value-of select="@DISPLAY"/></option>
</xsl:for-each>
</select>
</xsl:if>
</td>
<td><xsl:value-of select="@ID"/> </td>
<td><xsl:value-of select="@NAME"/> </td>
<xsl:if test="@DEPENDENT_ON != 'NULL'">
<xsl:variable name="dependent_on" select="@DEPENDENT_ON"/>
<xsl:for-each select="/LOB/ISSUE_TYPE/QUESTION">
<xsl:if test="@NAME=$dependent_on">
<td><xsl:value-of select="@DISPLAY"/></td>
</xsl:if>
</xsl:for-each>
<td><xsl:value-of select="@DEPENDENT_VALUE"/></td>
</xsl:if>
<xsl:if test="@DEPENDENT_ON = 'NULL'">
<td><xsl:value-of select="@DEPENDENT_ON"/></td>
<td><xsl:value-of select="@DEPENDENT_VALUE"/></td>
</xsl:if>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet></font>

===============================================================

References: http://www.w3schools.com/xsl/xsl_transformation.asp

Advertisement