JavaCreating Some XPath 2.0 Examples

Creating Some XPath 2.0 Examples

If you are unaware of the new features in XPath 2.0, see my earlier article What’s New in XPath 2.0?

There is relatively little software out there that supports XPath 2.0—in fact, besides XQuery processors like Galax, the only real XPath 2.0-enabled processor in popular use today is the Saxon XSLT application, which you can get for free at http://saxon.sourceforge.net. Because Saxon supports some XPath 2.0—as well as some XSLT 2.0—we'll use it in examples in our XPath 2.0 discussions.

If you want to follow along in these examples, you should download Saxon and unzip it. For our purposes, the important file is saxon7.jar, the Java Archive file which holds the Saxon implementation. Saxon is written in Java, so you'll need to have Java installed on your computer as well. Java is free and you can get the latest version at http://java.sun.com/j2se/.

Saxon supports a good deal of XSLT 2.0 as well as XPath 2.0, which is handy for use because we'll be able to put XPath 2.0 to work in XSLT 2.0 examples. For instance, take a look at the XML document in Listing 1, 01.xml. This document contains data on several cities, as you can see.

Listing 1 City Data in an XML Document (01.xml)

<?xml version="1.0" encoding="UTF-8"?> 
<document>

  <data 
    city="Glendale" 
    people="194973"
    state="California" 
  />

  <data 
    city="Fresno" 
    people="457652"
    state="California" 
  />

  <data 
    city="Sacramento" 
    people="407018"
    state="California" 
  />

  <data 
    city="Oakland" 
    people="399484"
    state="California" 
  />

  <data 
    city="Boston" 
    people="589141"
    state="Massachusetts" 
  />

  <data 
    city="Cambridge" 
    people="101359"
    state="Massachusetts" 
  />

  <data 
    city="Pittsburgh" 
    people="334563"
    state="Pennsylvania" 
  />

  <data 
    city="Erie" 
    people="103707"
    state="Pennsylvania" 
  />

  <data 
    city="Allentown" 
    people="106632"
    state="Pennsylvania" 
  />

</document>

We might want to use the new capabilities of XSLT 2.0 to process the data you see in 01.xml. Although this is not a book on XSLT 2.0, and although XSLT 2.0 is still in flux, we'll put Saxon to work here to show off some of the new power available in XSLT 2.0. For example, we can use the new <xsl:for-each-group> element to group the data on the various cities you see in 01.xml by state, displaying the sum of the people in all the cities in a particular state in an HTML table.

We start the XSLT 2.0 style sheet we'll use here this way—note that the version is 2.0:

<xsl:stylesheet version="2.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform"> 
    .
    .
    .

Here's how we group our data by state and loop over each group:

<xsl:for-each-group select="data" group-by="@state">
    .
    .
    .
</xsl:for-each-group>

Inside this loop, we can refer to the current group of cities in a particular state with the XSLT 2.0 current-group function like this, where we're summing up the people of the cities in each group state:

<xsl:for-each-group select="data" group-by="@state">
  <TR>
    <TD>
      <xsl:value-of select="@state"/>
    </TD>
    <TD>
      Cities People:
      <xsl:value-of 
        select="sum(current-group()/@people)"/>
    </TD>
    .
    .
    .
</xsl:for-each-group>

We'll also display the names of the cities in each group with <xsl:value-of>, as you see in 02.xsl (Listing 2).

Listing 2 An XSLT 2.0 Style Sheet (02.xsl)

<xsl:stylesheet version="2.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform"> 

  <xsl:template match="document">
  <HTML>

    <HEAD>
      <TITLE>City Data</TITLE>
    </HEAD>

    <BODY>

      <H1>City Data</H1>

      <TABLE BORDER="1" CELLPADDING="5">

<xsl:for-each-group select="data" group-by="@state">
  <TR>
    <TD>
      <xsl:value-of select="@state"/>
    </TD>
    <TD>
      Number of People:
      <xsl:value-of 
        select="sum(current-group()/@people)"/>
    </TD>
    <TD>
      Cities Used:
      <xsl:value-of select="current-group()/@city" 
        separator=" "/>
    </TD>
  </TR>
</xsl:for-each-group>

      </TABLE>

    </BODY>

  </HTML>
  </xsl:template>

</xsl:stylesheet> 

To make this example work with Saxon, you need to set the classpath environment variable to include the saxon7.jar file. To do that, move to the directory that contains 01.xml and 02.xsl and enter this line at the command prompt (in Windows, open a DOS command-prompt window to do this):

%set classpath=.;saxon7.jar

Next, to let Saxon convert 01.xml using 02.xsl, you can enter this line at the command prompt if you're in the same directory as 01.xml using 02.xsl:

%java net.sf.saxon.Transform 01.xml 02.xsl 

This assumes that the Java bin directory is in your machine's path; if not, you need to qualify "java" with the path to the Java bin directory, like this (in this case, the Java bin directory is C:javabin):

%C:javabinjava net.sf.saxon.Transform 01.xml 02.xsl 

When you execute this command line, this HTML will appear in the command-prompt window as the output from the Saxon XSLT processor:

<HTML>
  <HEAD>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
   <TITLE>City Data</TITLE>
  </HEAD>
  <BODY>
   <H1>City Data</H1>
   <TABLE BORDER="1" CELLPADDING="5">
     <TR>
      <TD>California</TD>
      <TD>
        Number of People:
        1459127
      </TD>
      <TD>
        Cities Used:
        Glendale Fresno Sacramento Oakland
      </TD>
     </TR>
     <TR>
      <TD>Massachusetts</TD>
      <TD>
        Number of People:
        690500
      </TD>
      <TD>
        Cities Used:
        Boston Cambridge
      </TD>
     </TR>
     <TR>
      <TD>Pennsylvania</TD>
      <TD>
        Number of People:
        544902
      </TD>
      <TD>
        Cities Used:
        Pittsburgh Erie Allentown
      </TD>
     </TR>
   </TABLE>
  </BODY>
</HTML>

To capture this HTML in an HTML document named results.html, you can use this command line:

%java net.sf.saxon.Transform 01.xml 02.xsl > results.html

And you can see what this HTML looks like in a browser in Figure 1.

Figure 1
Using XSLT 2.0 and Saxon.

Here's an example that uses the new XPath 2.0 max function to determine the maximum radius of any of the three planets in our planetary data XML document, 01.xml. You can see how that works in the XSLT 2.0 style sheet ch07_03.xsl in Listing 3.

Listing 3 An XSLT 2.0 Style Sheet Using the max Function (03.xsl)

<xsl:stylesheet version="2.0" xmlns_xsl="http://www.w3.org/1999/XSL/Transform"> 

  <xsl:template match="planets">
    <HTML>
      <HEAD>
        <TITLE>
          The Largest Planetary Radius 
        </TITLE>
      </HEAD>

      <BODY>
        <H1>
          The Largest Planetary Radius 
        </H1>
        <BR/>
        The largest planetary radius is
        <xsl:value-of select="max(//planet/radius)"/>
        miles.
      </BODY>

    </HTML>
  </xsl:template>

</xsl:stylesheet> 

Here's how you use this style sheet with Saxon:

%java net.sf.saxon.Transform 01.xml 03.xsl > results.html

And here's the HTML created—as you can see, the XPath 2.0 max function was indeed able to determine the maximum radius of the three planets:

<HTML>
  <HEAD>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  
   <TITLE>
     The Largest Planetary Radius 
     
   </TITLE>
  </HEAD>
  <BODY>
   <H1>
     The Largest Planetary Radius 
     
   </H1><BR>
   The largest planetary radius is
   3716
   miles.
   
  </BODY>
</HTML>

You can see what this HTML looks like in Figure 2.

Figure 2
Using the max function.

In Saxon, you have a tool that's useful in letting you test your XPath 2.0 expressions—even before XPath 2.0 becomes an official recommendation. Each version of Saxon includes documentation showing what parts of XPath 2.0 and XSLT 2.0 are supported.

About the Author

Steven Holzner is an award-winning author who has been writing about XML topics such as XSLT as long as they’ve been around. He’s the author of XPath Kick Start : Navigating XML with XPath 1.0 and 2.0 (published by Sams Publishing), and has written 67 books, all on programming topics, selling well over a million copies. His books have been translated into 16 languages around the world and include a good number of industry bestsellers. He’s a former contributing editor of PC Magazine, graduated from MIT, and received his Ph.D. at Cornell. He’s been on the faculty of both MIT and Cornell, and also teaches corporate seminars around the country.

Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.
Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.

Latest Posts

Related Stories