Combine the power of XPath and JSP tag libraries

Achieve simple data access in JSPs using XPath expressions

Java Server Pages and XML represent natural partners for building Web applications that use heterogeneous data sources. XML's DOM API provides a universal way to represent these diverse data sources. XPath provides a standard and simple syntax to access the DOM. JSP pages execute as Java servlets, typically in the context of a Web server where they generate session and data-dependent response documents. By combining these technologies, along with an XPath custom tag library, it's possible to make a standard and uniform approach to both representing the model data and accessing it.

The XPath tag library provides a framework within which dynamic content represented as a DOM document can be manipulated and inserted into a JSP to:

  • Simplify presentation code in the JSP and make it Java-free
  • Simplify templating or substitution points within the JSP
  • Remove complexity from dynamic data access, yet make it powerful

The XPath tag library combined with JSP further aids efficiency by engendering a clear separation between the role of a page author and a programmer.

This article covers intermediate-to-advanced JSP, XML, and DOM topics, so you may need to do some background reading in Resources to get up to speed.

Note: The XPath custom tag library is still in the proof-of-concept stage, hence it is not available as a standalone tag library. However, you can download the XPath-JSP Test Application WAR file and extract the relevant parts to create your own standalone tag library.

XPath syntax

XPath, a W3C recommendation since November 1999, provides an easy notation for specifying and selecting parts of an XML document. An XML document is a tree of elements with only one route or path from the root node of the tree to any other node of the tree. XPath defines this path.

Let's take an example XML document and some XPath expressions used to locate its parts.

The document below represents a user who has a userid and a password. Moreover, a user can have multiple roles, in this case two: Domain Administrator and Help Desk Administrator:

<user> 
            <userid>someone</userid> 
            <password>somewhere</password> 
            <roles> 
               <role id="admin">Domain Administrator</role> 
               <role id="helpdesk">Help Desk Administrator</role> 
             </roles> 
</user> 

The basic XPath syntax is similar to filesystem addressing. As such, if the path starts with /, then it represents an absolute path to the required element:

/user/userid/text()   select 'someone' 
/user/roles/role      select  all 'role' elements 
//role                select  all 'role' elements [ same as 2.] 
//role[@id='admin']/text()  select  'Domain Administrator' 
/user/roles/role[1]    select the first role element 
                          i.e. 'Domain Administrator' 
/user/roles/role[last()]   select the last role element
                          i.e. 'Help Desk Administrator'

The above examples represent just a sample of XPath's power. For a more complete list of XPath syntax see the XPath tutorial in Resources.

Architecture for a Web application using the XPath tag library

Having seen how XPath expressions can be used on an XML document, let us now discuss the architecture of a Web application using the XPath custom tag library, illustrated in Figure 1.

Figure 1. Web application architecture using the XPath custom tag library Click on thumbnail to view full-size image.

In this approach, presentation JSPs access the domain data or enterprise resources using XPath expressions. The domain data is represented as DOM document instances.

Page authors use the XPath custom tag library to embed XPath expressions in JSPs. Developers own the DOM document instances and are responsible for maintaining their state. Additionally, page authors could be given a DTD for the DOM document, providing its structure, which would be helpful in writing the XPath expressions.

Remember that XPath expressions are for access only, they cannot be used to update the state of a DOM document instance.

Examples of XPath expression in JSPs

We will create a sample to illustrate the various XPath custom tag library options. For this example, we assume that the application deals with customer orders. A sample Order XML document looks like this:

Order.xml

<ORDER>
<SHIPTO>
      <NAME>ALICE SMITH</NAME>
      <STREET>123 MAPLE STREET</STREET>
      <CITY>MILL VALLEY</CITY>
      <STATE>CA</STATE>
      <ZIP>90952</ZIP>
</SHIPTO>
<DATE>12-31-2000</DATE>
 <!-- Multiple item elements -->
 <ITEM>
      <TITLE>Twelve Songs of Christmas</TITLE>
      <ARTIST>JIM REEVES</ARTIST>
      <PRICE>15.95</PRICE>
 </ITEM>
  <ITEM>
        <TITLE>First Piano Concerto</TITLE>
        <ARTIST>>Janos</ARTIST>
        <PRICE>12.95</PRICE>
  </ITEM>
</ORDER>
 <!-More items here -->
 ...
 ...
 ...
</ORDER>

The Order XML document consists of a ShipTo, Date, and repeating Item elements. The application keeps an instance of the Order XML document in memory as a DOM document object. The examples below illustrate the usage of XPath expressions in a JSP, which accesses the sample Order DOM document.

Example 1: Simple data access and substitution

In our first example, the JSP uses XPath expressions to access the Order DOM instance. This example shows how data from the DOM instance is retrieved and substituted in the JSP:

viewOrder.jsp

<%@ page errorPage="error.jsp" %>
<%@ taglib uri="/src/tags/taglib.tld" prefix="mytag" %>
<html>
  <head>
    <title>View Orders</title>
  </head>
   <body bgcolor="white" link="#666699" vlink="#666699">
    <B> OrderDate: </B>  <mytag:getvalue select="/ORDER/DATE" /> <BR>
    <HR>
<!-- ifdef tag checks whether the Xpath expression is valid --> 
<mytag:ifdef select="/ORDER/SHIPTO" >
    <B> ShipTo: </B> <BR/>
    <mytag:getvalue select="/ORDER/SHIPTO/NAME" /> <BR>
    <mytag:getvalue select="/ORDER/SHIPTO/STREET" /> <BR>
    <mytag:getvalue select="/ORDER/SHIPTO/CITY" /> <BR>
    <mytag:getvalue select="/ORDER/SHIPTO/STATE" /> <BR>
    <mytag:getvalue select="/ORDER/SHIPTO/ZIP" /> <BR>
</mytag:ifdef>
    <HR>
          
    <!-- The -iterate custom tag- iterates through the repeating element "ITEM"  
     The -getvalue custom tag- substitutes the result of the XPATH expression for 
     the current iteration  -->  
    <mytag:iterate select="/ORDER/ITEM" > 
      <p>
         <B> ARTIST: </B> <mytag:getvalue select="./ARTIST" />    
         <B> TITLE : </B>  <mytag:getvalue select="./TITLE" />    
         <B> PRICE :  </B> <mytag:getvalue select="./PRICE" />    
     <BR>
               
    </mytag:iterate>  
    </body>
    </html>  

The code above uses three tags from the XPath tag library: getvalue, ifdef, and iterate. All three tags have a select attribute that specifies an XPath expression.

The getvalue applies the XPath expression specified in the select, on the Order DOM document instance and substitutes the result.

The conditional ifdef tag evaluates its body content only if the XPath expressions specified in its select are valid.

iterate, an iteration tag, parses its body contents for each iteration. In this case, the select attribute specifies a node set to be retrieved which is then iterated over. Note that the getvalue tag, when used within the iterate tag, specifies a relative XPath expression in its select attribute.

The example above covers simple data access, substitution, and control flow using XPath expressions in a JSP. The next example discusses attribute value substitution.

Example 2: Attribute value substitution

In our second example, the JSP uses XPath expressions to access the ShipTo data from the DOM instance, which is then edited using an HTML form. Note the use of the template: prefix for attribute value substitution:

editShipTo.jsp

<%@ taglib uri="/src/tags/taglib.tld" prefix="mytag" %>  
   
   <html>  
              .....  
              .....  
 
     <form action="/editshipto.do" method="POST" > 
     SHIP TO: <BR/>
     
     <!-- Attribute value substitution is done by using the 'template:' prefix 
        and by enclosing the content in the XPathTemplate tag -->
     <mytag:XPathTemplate>
       NAME: <input type="text" name="name"          
                 template:value="/ORDER/SHIPTO/NAME"/>  <BR/>
    
       STREET: <input type="text" name="street"              
                 template:value="/ORDER/SHIPTO/STREET"/>  <BR/>
     
       CITY : <input type="text" name="city"             
                 template:value="/ORDER/SHIPTO/CITY"/>  <BR/>
    
       STATE: <input type="text" name="state"            
                 template:value="/ORDER/SHIPTO/STATE"/>  <BR/>
       ZIP:  <input type="text" name="zip"           
                 template:value="/ORDER/SHIPTO/ZIP"/>  
                 
     </mytag:XPathTemplate>
      </form> 
        ..... 
        ..... 
    </html> 

The code above illustrates the use of the XPathTemplate container tag that enables XPath expression results to be substituted in attribute values. To achieve this, the template: keyword is used to prefix attribute values that need to be evaluated, as shown in the example above.

The XPathTemplate template tag parses its body content, looking for elements that have attributes starting with the template: prefix. When it finds one, it applies the XPath expression on the DOM document instance and rewrites the attribute and its value without the template: prefix. In the example above we saw how XPath expressions are used in attribute values and how the XPathTemplate tag is used for attribute value substitution. In the next section, we will see the various custom tags available as part of the XPath custom tag library.

The XPath custom tag library

We will now see the various tags and their attributes available in the XPath custom tag library. For each tag you'll find the name, description, and attribute details.

Tag: XPathTemplate

Description:

  • A container/super tag that enables XPath expressions in attributes
  • The body of this tag could be HTML or well-formed XML
  • For attribute-value substitution, the prefix template: is used on the attribute
  • For element substitution, the iterate tag or getvalue tag mentioned below are used

Attributes:

  • Attribute name: content
  • Attribute value: html (default) or xml

Tag: iterate

Description:

  • Allows iteration over an XPath expression that results in multiple nodes
  • Used in conjunction with the getvalue tag

Attributes:

  • Attribute name: select
  • Attribute value: an XPath expression

Tag: getvalue

Description:

  • Substitutes the result of the XPath expression
  • The tag implementation checks whether this tag has an enclosing iterate tag and substitutes the value appropriately

Attributes:

  • Attribute name: select
  • Attribute value: An XPath expression

Tag: ifdef

Description:

  • Tests if the XPath expression is valid and maps to a node
  • If the test returns true, then the body of the tag is evaluated

Attributes:

  • Attribute name: select
  • Attribute value: an XPath expression

Tag: ifnodef

Description:

  • Tests if the XPath expression is invalid or there is no corresponding node for the XPath expression
  • If true, then the body of the tag is evaluated

Attributes:

  • Attribute name: select
  • Attribute value: an XPath expression

Tag: gencontent

Description:

  • Creates a DOM document instance in session scope for the XML in its body
  • If its debug attribute is set to on, it serializes the DOM to the standard output

Attributes:

  • Attribute name: debug
  • Attribute value: on or off

Representing domain data as DOM documents

The previous sections focused on how XPath expressions are used in JSPs to access DOM document instances. Now let us briefly discuss two techniques for creating a DOM document instance to represent the domain data.

Domain data can be represented as a DOM document in two ways:

  1. Domain data classes, for example Order.java, could return a DOM document using a toDOM() method
  2. As a set of JavaBean objects translated to DOM document instances at runtime

Of the two, the second approach proves more elegant, but it carries a performance penalty since the translation from a JavaBean to a DOM document acts as an overhead. The JOX Java libraries provide a nice framework for translating JavaBeans to XML.

Map XPath expressions to DOM instances

So how does an XPath expression get mapped to a DOM document instance?

After the DOM document representing the data available to a JSP is created, it is put in one of the application, request, session, or page scopes. The DOM document instance's name or key is the same as the name of the document element.

Using Order.xml as an example, a DOM document representation of this XML file will be stored in either one of the scopes, with the name Order, which is the name of the document element in Order.xml.

1 2 Page
Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more