Web 2.0 applications, which offer users a more dynamic experience, often use Asynchronous JavaScript and XML (Ajax). Once you load a master HTML document, you can use Ajax to update Web content without refreshing the whole Web page. With Ajax, you can treat Web content as data fragments, pulling in each on demand. In addition, client-side JavaScript processes can format the data on their own, whether using data in plain-text, XML, JavaScript Object Notation (JSON) objects, or HTML fragments.
The new paradigm of Web application development goes far beyond the traditional Model-View-Controller (MVC) model. Unfortunately, many Ajax Web application frameworks, such as Direct Web Remoting (DWR) and JavaServer Faces (JSF), can present challenges. Although Ajax frameworks can simplify application development in many ways, the mechanism of the framework more or less controls the Web content. Many existing Ajax frameworks don't provide universal solutions that can handle real-world complexity, especially with the increased requirements for data aggregation from XML and content syndication from RSS feeds. These new requirements dictate the needs for effective Web service support on the server side.
To take advantage of these changing technologies, you can create a mashup application that couples Web content with XML data and Web services. I'll show you how to create a mashup application that uses XQuery, a promising technology that deals with Web services and XML.
The sample mashup application allows users to search for new books in a public library system that consists of all the libraries in the region. At each library, librarians order new books regularly without knowing whether other public libraries have them. The application publishes and shares its own holding information through a Web service. The application aggregates all the new book information from libraries and provides users with search functions for new books.
XQuery is a World Wide Web Consortium (W3C) standard designed specifically for extracting information from XML documentation. Its XML-processing abilities have many advantages over existing object-programming models, such as the Java™ Document Object Model (DOM) API (see Resources for several related IBM developerWorks references).
Simplifying server-side XML processing
You can use JavaScript to parse and process XML with the DOM API. However, this doesn't mean you can use JavaScript to do all XML processing from the client side. This is especially true when the business logic processes become more complex. how to balance client- and server-side XML processing is one of the primary concerns when you design Web applications. XQuery offloads the complex business logic to the server side, which has many advantages. For example, you can consider security issues more thoroughly, and you can perform application maintenance more easily. In addition, XQuery functions simplify overall development efforts.
Limiting content transmitted over the network
When you design a Web application, you must consider how large the content is and how often it is transmitted over the network. Each call to the server introduces overhead. Avoid making an asynchronous call for every keystroke or mouse move. When you don't use calls to the server properly, you can easily bog down the application with unnecessary network traffic and workload.
A 56K dial-up network connection takes almost 14 seconds to transmit 100KB of Web content. XQuery provides a better user experience by reducing the size of content transmitted over the network. For example, to limit the XML content size, you can call the standard XQuery function string-length() before you return the XML. Rather than limit the XML content size, the sample application limits the size of the XML elements to 100 book items by counting the nodes.
Integrating multiple search fields
Sometimes, Web searches use multiple entries for search criteria. For example, the sample application offers users three choices. They can input one of the fields or any combination of up to three fields. XQuery functions combined with XPath expressions provide a powerful search mechanism for implementing the search requirements.
Integrating business logic without additional programming
XQuery is a declarative query language. To simplify the integration of existing data and services using XML, it encapsulates the business logic in a compact fashion. The query output can be in user-defined formats, so you can implement the business logic easily without additional programming efforts.
Figure 1 shows the application design. The server responses can be in any format that the client requires, including partial HTML, XML, plain-text, or JSON object. The embedded XQuery engine executes predefined queries based on dynamic search criteria. You define the business logic and the presentation logic in the queries. The XML data can come from many data resources, such as a file system, a database, or a URI, which presents a Representational State Transfer (REST) Web service.
Figure 1. Sample application architecture overview
You can embed the XQuery engine using the basic Java servlet. You can select from many XQuery engines, including those from a vendor or from open source. This application uses open source Saxon 8.7 (see Listing 1).
Listing 1. Embed the Saxon XQuery engine
Configuration config = new Configuration(); staticQueryContext = new StaticQueryContext(config); dynamicQueryContext = new DynamicQueryContext(config); |
Collecting XML data and defining data formats
To collect your XML data, you need to consider where the XML data comes from, whether you need to use a Document Type Definition (DTD) or schema, and whether you need to execute the XML validation. The sample application uses a DTD for the XML data format, and it assumes that all the data sources before being processed by XQuery are valid XML documents against the DTD. Listing 2 illustrates a sample XML data format.
Listing 2. Sample XML data format
<?xml version="1.0" encoding="UTF-8"? > <!DOCTYPE library SYSTEM "dtd/book.dtd"> <booklist> <book category="COOKING"> <title lang="en">Everyday Italian</title> <authors> <author>Giada De Laurentiis</author> </authors> <isbn></isbn> <numberCopies>1</numberCopies> <status>On Shelf</status> <year>2005</year> <library>John C. Hart Library</library> <price>30.00</price> </book> ... </booklist> |
Defining XQuery queries with business logic
In the XQuery business logic, three fields are used to search books, and six query strategies need to be constructed in considering the cases. In addition, the default scenario needs to be considered if no search parameters are given. Unlike a traditional Web application framework, XQuery can construct the business logic easily in a query file. You can update this file later on if necessary, even without stopping the running applications. For example, you could change the queries for books published within the last three years.
The XML data might come from many resources. The book_collection.xml file defines a collection of XML data. One source of XML data comes from the sample Web application itself at http://localhost:9080/bookinfor/newbooks_localhost.xml. When you test the sample application, make sure you set the Web application context root correctly as bookinfor. Listing 3 illustrates a collection of XML data.
Listing 3. XQuery collection
<collection > <doc href="newbooks_library_01.xml"/> <doc href="newbooks_library_02.xml"/> <doc href="newbooks_library_03.xml"/> <doc href="newbooks_library_04.xml"/> <doc href="http://localhost:9080/bookinfor/newbooks_localhost.xml"/> </collection> |
Be sure to consider performance concerns when you design your XQuery Web application. In this case, I set the threshold of the search output to 100 books. Compared with conventional object programming such as Java, XQuery can implement business logic without requiring development efforts on the server side. When dealing with large XML data, you can combine the embedded XQuery engine with the IBM DB2 Viper release, which can handle a large amount of XML content up to 2GB. Listing 4 illustrates the application business logic in the booklist_app.xql file.
Listing 4. XQuery with the simple business logic
(: -------------------------- :)
(: declares ...... :)
(: -------------------------- :)
declare namespace local = "http://localhost/ns";
declare variable $title as xs:string external;
declare variable $author as xs:string external;
declare variable $year as xs:string external;
declare variable $emptymsg as xs:string external;
declare variable $oversizedmsg as xs:string external;
declare variable $outputformat as xs:string external;
(: -------------------------- :)
(: functions :)
(: -------------------------- :)
declare function local:error_view($helpmsg as xs:string) {
if($helpmsg) then $helpmsg
else ('<report status="0">Please call 1-800-123-4567</report>')
};
declare function local:html_view($doc) {
<table>
<tr> <td>Library Name</td>
<td>Book Title</td>
<td>Number of Copies</td>
<td>Status</td>
</tr>
{ for $book in $doc/book
where $book/title/@lang="en"
order by $book/library
return <tr>
<td>{$book/library}</td>
<td>{$book/title/text()}</td>
<td>{$book/numberCopies}</td>
<td>{$book/status}</td>
</tr>
}
</table>
};
(: -------------------------- :)
(: the business logic :)
(: -------------------------- :)
let $docs := ('bookinfor/book_collection.xml')
let $searchdoc := (
<report status='1'>
{
if($title and $year and $author) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)
and (year = $year)]
where contains($doc//authors, $author)
return $doc
) else if($title and $year ) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)
and (year = $year)]
order by $doc//booklist/book/title
return ($doc)
) else if($title and $author ) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)]
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($author and $year ) then (
for $doc in collection($docs)//booklist/book[(year=$year)]
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($title) then (
for $doc in collection($docs)//booklist/book[contains(title,$title)]
order by $doc//booklist/book/title
return ($doc)
) else if($author) then (
for $doc in collection($docs)//booklist/book
where contains($doc//authors, $author)
order by $doc//booklist/book/title
return ($doc)
) else if($year) then (
for $doc in collection($docs)//booklist/book[(year=$year)]
order by $doc//booklist/book/title
return ($doc)
) else (
for $doc in collection($docs)
return ($doc//booklist/book)
)
}
</report>
)
(: -------------------------- :)
(: return results :)
(: -------------------------- :)
return if(count($searchdoc//book) eq 0) then local:error_view($emptymsg )
else if(count($searchdoc//book) gt 100)
then local:error_view($oversizedmsg)
else if($outputformat eq $html)
then local:html_view($searchdoc)
else $searchdoc
|
Calling XQuery queries in the application
To make the queries executable in the embedded engine, you need to set the related parameters and precompile the queries. After the queries are executed, the final output is sent back to the Web client. Client-side JavaScript code assembles the data and presents it to users. Please note that the sample application sets the directory c:/tmp/xmldatasources/ as the static query context. Make sure the bookinfor directory exists within it, and copy the XML data files over before testing the sample application. Listing 5 illustrates the embedded XQuery calls.
Listing 5. Call XQuery queries in the application
dynamicQueryContext.setParameter("emptymsg", "No results exist!");
dynamicQueryContext.setParameter("oversizedmsg",
"Too many results, please refine queries");
staticQueryContext.setBaseURI("c:/tmp/xmldatasources/");
fileReader = new FileReader(request.getRealPath("/")+ "/queries/booklist_app.xql");
queryExpression = staticQueryContext.compileQuery(fileReader);
writer = new StringWriter();
StreamResult result = new StreamResult(writer);
Properties props = new Properties();
queryExpression.run(dynamicQueryContext, result, props);
retContent = writer.getBuffer();
|
Note that XQuery technology still has some limitations and a learning curve. Keep in mind that no single technology can solve all your business issues. Chances are you'll still need to combine XQuery with other technologies such as XPath and XSLT to make your mashup achievable.
Although XQuery doesn't have a final standard yet, its basic features and functions have drawn much attention. It is powerful in processing XML and has shown great potential for setting up mashups. Once you implement your dynamic Web application with XQuery, you can quickly scale up your Web site and achieve your business goal in a comparatively simple and agile manner.
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample code for XQuery to power mashups | x-xquerymashup.zip | 12KB | HTTP |
Information about download methods
Learn
- Mastering Ajax, Part I: Introduction to Ajax by Brett McLaughlin (developerWorks, December 2005): Learn how Ajax technologies work together to transform clunky Web interfaces into interactive Ajax applications.
- Considering Ajax, Part 2: Change your life with mashups by Chris Laffra (developerWorks, May 2006): Read how Ajax powers user-directed mashups of content on personalized Web pages.
- Debunking XQuery myths and misunderstandings by Frank Cohen (developerWorks, July 2005): Check out many of the myths and misunderstandings that surround XQuery.
- Java theory and practice: Screen-scraping with XQuery by Brian Goetz (developerWorks, March 2005): Look at how to use XQuery effectively as an HTML screen-scraping engine.
- Develop Java applications for DB2 XML data by Cynthia M. Saracco (developerWorks, May 2006): Write Java apps and create stored procedures that access XML data plus learn to insert, query, update, and delete XML data.
- W3C XML Query (XQuery): Check out the XQuery home pages for specifications and more.
- Saxon 8.7: Learn to embed an XQuery engine.
- IBM XML 1.1 certification: Find out how you can become an IBM Certified Developer in XML 1.1 and related technologies.
- XML: See developerWorks XML Zone for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
- developerWorks technical events and webcasts: Stay current with technology in these sessions.
Get products and technologies
- IBM DB2 9 Viper release: Download a free trial version.
Discuss
- XML zone discussion forums: Participate in any of several XML-centered forums.
Comments (Undergoing maintenance)





