Skip to main content

Power your mashups with XQuery

Ning Yan (nyan@us.ibm.com), Software Engineer, IBM
Ning Yan is a software engineer at IBM. His expertise is in Web application development and business solutions that include DB2, WebSphere®, and open source technologies. His current interests include social computing technologies and Web services.

Summary:  Today Web developers and architects can develop dynamic Web applications that offer a better user experience. The changing paradigm of Web application frameworks presents numerous challenges. Learn how XQuery can be effective in facing these challenges, as you create a sample mashup application.

Date:  25 Jul 2006
Level:  Introductory
Activity:  2775 views

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 to the rescue

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.


Sample application

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
Sample application architecture overview

Embedding the XQuery engine

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();	      


Conclusion

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.



Download

DescriptionNameSizeDownload method
Sample code for XQuery to power mashupsx-xquerymashup.zip12KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

About the author

Ning Yan is a software engineer at IBM. His expertise is in Web application development and business solutions that include DB2, WebSphere®, and open source technologies. His current interests include social computing technologies and Web services.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Web development
ArticleID=148380
ArticleTitle=Power your mashups with XQuery
publish-date=07252006
author1-email=nyan@us.ibm.com
author1-email-cc=dwxed@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers