Home | | Service Oriented Architecture | Advanced Features of XSLT

Chapter: XML and Web Services : Building XML-Based Applications : Transforming XML with XSL

Advanced Features of XSLT

In this section, you’ll learn how to loop over a collection of XML elements, sort the elements, and perform conditional filtering on the data.

Advanced Features of XSLT

 

The previous section covered the basics of XSLT processing. Now that you have the required components for XSLT processing installed and configured, we’ll explore some advanced XSLT concepts. In this section, you’ll learn how to loop over a collection of XML elements, sort the elements, and perform conditional filtering on the data.

 

Looping

 

The XSLT element <xsl:for-each> is used for looping through a list of elements. This is very useful when you have a collection of related items and you’d like to process them in a sequential fashion. The <xsl:for-each> element is commonly used in the Web development world to convert an XML document to an HTML table.

 

Here’s the syntax for <xsl:for-each>:

 

<xsl:for-each select=node-set-expression> <!-- content -->

 

</xsl:for-each>

 

The <xsl:for-each> element has a required attribute: select. The value of the select attribute is an expression. The expression contains an XPath expression for selecting the appropriate elements from the list.

 

Let’s take the previous book.xml example one step further. Instead of describing a single book, let’s create an XML document that contains a list of books. This could describe the books available at an e-commerce site or a list of books available in your company’s technical library. Listing 9.8 contains the file booklist.xml.

 

LISTING 9.8    <install_dir>\ch9_xsl\public_html\loop\booklist.xml

 

<?xml version=”1.0”?> <booklist>

 

<book>

 

<author>Michael Daconta et al</author> <title>XML Development with Java 2</title> <category>Java</category>

 

<price currency=”USD”>37.99</price> </book>

 

<book>

 

<author>Mark Grand</author> <title>Patterns in Java</title> <category>Java</category>

 

<price currency=”USD”>44.99</price> </book>

 

<book>

 

<author>Richard  Monson-Haefel</author>

<title>Enterprise JavaBeans</title> <category>Java</category>

 

<price currency=”USD”>34.95</price> </book>

 

<book>

 

<author>Chad Darby et al</author> <title>Professional Java E-Commerce</title> <category>Java</category>

 

<price currency=”USD”>59.95</price> </book>

 

<book>

 

<author>E. Lynn Harris</author> <title>Any Way The Wind Blows</title> <category>Fiction-Romance</category> <price currency=”USD”>19.95</price>

 

</book>

 

<book>

 

<author>E. Lynn Harris</author> <title>Invisible Life</title> <category>Fiction-Romance</category> <price currency=”USD”>16.95</price>

 

</book>

 

<book>

 

<author>E. Lynn Harris</author> <title>And This Too Shall Pass</title> <category>Fiction-Romance</category> <price currency=”USD”>18.95</price>

 

</book>

 

<book>

 

<author>Tom Clancy</author> <title>Executive Orders</title> <category>Fiction-Thriller</category> <price currency=”USD”>7.99</price>

 

</book>

 

<book>

 

<author>Tom Clancy</author> <title>Hunt for Red October</title> <category>Fiction-Thriller</category> <price currency=”USD”>27.95</price>

 

</book>

 

<book>

 

<author>Tom Clancy</author> <title>The Sum of All Fears</title> <category>Fiction-Thriller</category> <price currency=”USD”>7.99</price>

 

</book>

 

</booklist>

 

Now, let’s design an XSL style sheet to convert the XML document to an HTML table. The <xsl:for-each> element loops over a list of items. This example performs a loop for each <book> element in the <booklist> element. This process is described in the select attribute with the expression booklist/book. See the following code snippet:

 

<xsl:for-each  select=”booklist/book”  >

 

<!-- insert table rows and table data --> </xsl:for-each>

 

Inside of the <xsl:for-each> element, the appropriate HTML elements are used for the table rows and table data. To retrieve the data from the XML document, each table cell uses the <xsl:value-of> element. Listing 9.9 contains the complete style sheet,

 

booklist_loop.xsl.

 

LISTING 9.9    <install_dir>\ch9_xsl\public_html\loop\booklist_loop.xsl

 

<?xml  version=”1.0”?>

 

<xsl:stylesheet  xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”  version=”1.0”>

 

<xsl:template match=”/”> <html><body>

 

<h3>Looping Example</h3> <hr></hr>

 

<table border=”1” cellpadding=”5”> <tr>

 

<th>Author</th>

 

<th>Title</th>

 

<th>Category</th>

 

<th>Price</th>

 

</tr>

 

<!-- Perform  loop  for  each  book  in  the  book  list  -->

 

<xsl:for-each select=”booklist/book” >

 

 

<tr>                 

<td>     <xsl:value-of select=”author” /> </td>

<td>     <xsl:value-of select=”title” />  </td>

<td>     <xsl:value-of select=”category” />       </td>

<td>     <xsl:value-of select=”price” />            </td>

</tr>                

</xsl:for-each>

 

</table>

 

</body></html>

 

</xsl:template>

 

</xsl:stylesheet>

 

You can test the server-side scripts using the techniques presented earlier in this chapter. The test files are named booklist_test.jsp and booklist_test.asp. They are located in the directory <install_dir>\ch9_xsl\public_html\loop.

 

The server-side scripts refer to the appropriate XML document and XSL style sheet. Listing 9.10 contains the code for booklist_test.jsp.

 

LISTING 9.10  <install_dir>\ch9_xsl\public_html\loop\book_test.jsp

 

<%@  taglib  uri=”http://jakarta.apache.org/taglibs/xsl-1.0”  prefix=”jakarta”  %>

 

<jakarta:apply  xml=”/loop/booklist.xml”  xsl=”/loop/booklist_loop.xsl”  />

 

To view the test file, start the Tomcat server. In the Web browser, open http:// localhost:8080/bookch9/loop/booklist_test.jsp. Figure 9.8 shows the result.


 

You can also test this example using the client-side techniques described earlier in the chapter by adding a reference to the XSL in the XML document.

Sorting

 

In XSLT, the <xsl:sort> element is used for sorting the XML data. It is possible to sort based on a single key or multiple keys. The syntax for the <xsl:sort> element is shown here:

 

<xsl:sort

 

select  =  string-expression

 

order = { “ascending” | “descending” } data-type = { “text” | “number” }

 

case-order = {“upper-first” | “lower-first” } lang = { nmtoken } />

 

The <xsl:sort> element is used in conjunction with the <xsl:for-each> element. For example, the following code snippet sorts the book titles in alphabetical order:

 

<!-- Sort by the book title --> <xsl:for-each select=”booklist/book” >

 

<xsl:sort  select=”title”  />

 

<!-- insert table rows and table data --> </xsl:for-each>

 

Sort Order: Ascending or Descending?

 

By default, the information is sorted in ascending order. Set the order attribute to descending for a descending sort. The following code snippet sorts the titles in descend-ing order:

 

<!-- Sort by the book title, descending --> <xsl:for-each select=”booklist/book”>

 

<xsl:sort select=”title” order=”descending”/> <!-- insert table rows and table data -->

 

</xsl:for-each>

 

It is important to note that the <xsl:sort> element assumes that the sort key is a text element. If you need to sort numerical data, you have to set the data-type attribute to number. If you don’t set the data-type attribute, the XSLT processor will use the default value, text. When sorting numerical data, the default value of text will not generate the desired output. To demonstrate this point, let’s attempt to sort the books in booklist.xml by price. The following code snippet purposefully omits the data-type attribute:

 

<xsl:for-each  select=”booklist/book”>

 

<xsl:sort select=”price” />

 

<tr>

 

<td> <xsl:value-of  select=”author”  />  </td>

<td>  <xsl:value-of  select=”title”   />         </td>

<td>  <xsl:value-of select=”category”  />    </td>

<td>  <xsl:value-of select=”price”  />         </td>

</tr> </xsl:for-each>

 

When applied to booklist.xml, this style sheet fragment generates the output in Figure 9.9.


Notice that the prices are not sorted in an ascending order.

 

To achieve numerical sorting, you have to specify <xsl:sort select=”price” data-type=”number” />. Listing 9.11 provides the correct usage of the <xsl:sort> element for numerical sorting.

 

 

LISTING 9.11  <install_dir>\ch9_xsl\public_html\sort\booklist_sort.xsl

 

<?xml  version=”1.0”?>

 

<xsl:stylesheet  xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”  version=”1.0”>

 

<xsl:template match=”/”> <html><body>

 

<h3>Sorting Example: By Price</h3> <hr></hr>

 

<table border=”1” cellpadding=”5”> <tr>

 

<th>Author</th>

 

<th>Title</th>

 

<th>Category</th>

 

<th>Price</th>

</tr>

 

<!-- Perform loop for each book in the book list --> <xsl:for-each select=”booklist/book” >

 

<xsl:sort select=”price” order=”ascending” data-type=”number” />

<tr>                             

<td> <xsl:value-of  select=”author”  />  </td>

<td> <xsl:value-of  select=”title”  />    </td>

<td> <xsl:value-of  select=”category”  />         </td>

<td> <xsl:value-of  select=”price”  />  </td>

</tr>                            

</xsl:for-each> </table>

 

</body></html>

 

</xsl:template>

 

</xsl:stylesheet>

 

When applied to booklist.xml, the revised style sheet generates the correct output, as shown in Figure 9.10.

 

 

Sorting by Case

 

The case-order attribute is used to specify whether uppercase or lowercase has prece-dence during the sort. For example, if the case-order attribute is set to upper-case, then

 

a  b  A  B

 

is sorted as follows:

 

A  a  B  b

 

If the lower-case attribute value is applied, then

 

a  b  A  B

 

is sorted like this:

 

a  A  b  B

 

The case-order attribute should only be used when the data-type attribute is set to

 

text.

 

Sorting with Multiple Keys

 

In certain situations, you might want to sort using multiple keys. For example, you could sort the books by category and then by price. This is accomplished by inserting multiple <xsl:sort> elements within an <xsl:for-each> element. Listing 9.12 sorts by category and then by price.

 

LISTING 9.12  <install_dir>\ch9_xsl\public_html\sort\booklist_sort_

 

categoryprice.xsl

 

<?xml  version=”1.0”?>

 

<xsl:stylesheet  xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”  version=”1.0”>

<xsl:template match=”/”> <html><body>

 

<h3>Sorting Example: By Price</h3> <hr></hr>

 

<table border=”1” cellpadding=”5”> <tr>

 

<th>Author</th>

 

<th>Title</th>

 

<th>Category</th>

 

<th>Price</th>

 

</tr>

 

<!-- Perform  loop  for  each  book  in  the  book  list  -->

 

<xsl:for-each select=”booklist/book” > <xsl:sort select=”category” />

 

<xsl:sort select=”price” data-type=”number” /> <tr>

 

 

<td>                    <xsl:value-of select=”author” /> </td>

<td>                    <xsl:value-of select=”title”    />         </td>

<td>                    <xsl:value-of select=”category” />     </td>

<td>                    <xsl:value-of select=”price”  />         </td>

</tr> </xsl:for-each>

 

</table>

 

</body></html>

 

</xsl:template>

 

</xsl:stylesheet>

 

When applied to booklist.xml, this style sheet generates the output shown in Figure 9.11. The implementation details are left as an exercise for you, the reader.

 

The server-side test scripts are available in the directory <install_dir>\ch9_xsl\pub-lic_html\sort.

 

Conditionals

 

During an XSLT transformation, the style sheet can perform conditional tests on the data. XSLT contains a very simple if-then conditional. The syntax for the <xsl:if> element is shown here:

 

<xsl:if test=Boolean-expression> <!-- content -->

 

</xsl:if>

 

The test attribute refers to a Boolean expression. If the Boolean expression evaluates to true, the content within the <xsl:if> element is included in the output.


The following code snippet performs a test for Fiction-Thriller books:

 

<xsl:for-each select=”booklist/book” > <tr>

 

<xsl:if test=”category=’Fiction-Thriller’”> <xsl:attribute name=”bgcolor”>red</xsl:attribute>

</xsl:if>

<td>  <xsl:value-of  select=”author”  />  </td>

<td>  <xsl:value-of  select=”title”  />  </td>

<td>  <xsl:value-of  select=”category”  />  </td>

<td>  <xsl:value-of  select=”price”  />  </td>

</tr> </xsl:for-each>

 

If a Fiction-Thriller book is found, the background color of the row is set to red. In this example, we’ve introduced a new XSLT element, <xsl:attribute>. The

 

<xsl:attribute> element creates a new attribute for the parent element. In this example, the parent is the <tr> element. If the conditional is true, the <tr> element will have the attribute bgcolor and its value set to red. The end result is <tr bgcolor=”red”>.

 

When applied to booklist.xml, the XSLT processor generates the output shown in

 

Figure 9.12. The server-side test scripts are available in the directory ch9_xsl\public_html\if.


Filters

 

In relation to conditional tests, XSLT can also filter the data based on a given expression. When data is selected using the <xsl:for-each> element, the expression can contain a filter. For example, you can filter the data to contain only Java books. The following code snippet performs the desired operation:

 

<xsl:for-each select=”booklist/book[category=’Java’]” >

 

<tr>

 

 

<td> <xsl:value-of  select=”author”  />  </td>

<td> <xsl:value-of  select=”title”         />         </td>

<td> <xsl:value-of       select=”category”  />    </td>

<td> <xsl:value-of       select=”price”  />         </td>

</tr> </xsl:for-each>

 

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
XML and Web Services : Building XML-Based Applications : Transforming XML with XSL : Advanced Features of XSLT |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.