Using XQL to query Java and XML data in client/server and distributed environments requires more than the ability to use it on the database server. In this article, I’ll explore using XQL to retrieve results from Sybase ASE from a stand-alone client application, a JDBC client, and an Enterprise JavaBean (EJB) server bean and client. I’ll also examine the surprisingly few methods needed to facilitate this powerful technology.

Did you miss an earlier installment?

Check out these other articles in the series to get an introduction or a refresher:

Using XQL to develop stand-alone applications
It’s easy to use XQL to develop stand-alone applications, JDBC clients, JavaBeans, and EJBs to process XML data. The query() and parse() methods in the com.sybase.xml.xql.Xql package enable you to query and parse XML documents. Because you can write stand-alone applications, you don’t have to depend on Adaptive Server to supply the result set. Instead, you can query XML documents stored as operating system files or stored on a Web server. Let’s take a closer look with an example.

Stand-alone application
The example in Listing A uses the FileInputStream() query to read an XML file (bookstore.xml) and the URL() method to read a Web page named bookstore.xml, which contains information about all the books in the bookstore.

In addition, the validate option invokes a parser that makes sure the XML document you’re querying conforms to its document type definition (DTD). Your stand-alone XML document must have a valid DTD before you run the validate option. Validate is optional, so avoid it if a DTD doesn’t exist.

For example, this command ensures the bookstore.xml document conforms to its DTD:
java com.sybase.xml.xql.XqlDriver -qstring “/bookstore” -validate
-infile bookstore.xml

JDBC client
The following code fragment uses the Xql.query method to query the xmlcol column in the XMLTEXT file via a JDBC connection:
String selectQuery = “select xmlcol from XMLTEXT”;
Statement stmt = _con.createStatement();
ResultSet rs = (SybResultSet)stmt.executeQuery(selectQuery);
String result;
InputStream is = null;
while ((rs != null) && ( {        
is = rs.getAsciiStream(1);
result = Xql.query(“/bookstore/book/author”, is);

This next example assumes that the parsed XML data is stored in an image column of the XMLDOC table. Although this application fetches an image column as a binary stream, it doesn’t parse this during the query because it identifies the content of this binary stream as a parsed XML document. Instead, the application creates a SybXmlStream instance from it and then executes the query. All this is done using the Xql.query() method, and it does not require any input from the user.
String selectQuery = “select xmlcol from XMLDOC”;
Statement stmt = _con.createStatement();
ResultSet rs = (SybResultSet)stmt.executeQuery(selectQuery);
InputStream is = null;
String result
while ((rs != null) && (  {
is = rs.getBinaryStream(1);
result = Xql.query(“/bookstore/book/author/first-name”, is));

EJB example
EJB code fragments that serve as query engines on an EJB server may be written in.

The code fragment below includes an EJB called XmlBean. XmlBean includes the query() method, which allows you to query any XML document on the Web. In this component, query() first creates an XmlDoc object, then queries the document. Listing B contains code examples.

Special XQL data types
Using the available XQL Java methods requires the use of special data types. The following special data types are required in order to use XQL Java code:

  • ·        sybase.aseutils.SybXmlStream defines an interface that an InputStream needs to access parsed XML data while querying.
  • · holds the parsed XML document in main memory, an implementation of SybXMLStream that Sybase provides. The parse() method returns an instance of SybMemXmlStream after parsing an XML document.
  • ·{file_name} allows you to query a file in which you have stored a parsed XML document where file_name is the name of the file in which you stored the parsed XML document.

In the following example, a member of the RandomAccessFile reads a file and positions the data stream:
SybXmlStream xis = Xql.parse(“<xml>..</xml>”);
FileOutputStream ofs = new FileOutputStream(“”);
SybXmlStream is = new SybFileXmlStream(“”);
String result = Xql.query(“/bookstore/book/author”, is);

Sybase XQL methods
The power of XQL is not in the number of methods provided but rather in the power of the query string used in the query() methods and the flexibility of where the XML document source may be located via the different usages of the parse() methods. You should note that there are things the parse methods won’t do: validate the document if a DTD is provided; parse any external DTDs; perform any external links (for example, XLinks); or navigate through IDREFs.

The following methods are all that are needed to extend Java to accommodate XQL using com.sybase.xml.xql.Xql:

  • ·        parse(String xmlDoc) takes a Java string as an argument and returns SybXmlStream. You can use this to query a document using XQL where String is a Java string and xml_document is the XML document in which the string is located.
  • ·        parse(InputStream xml_document, boolean validate) takes an InputStream and a boolean flag as arguments where xml_document is the XML document in which the input stream originates and the flag indicates that the parser should validate the document according to a specified DTD. This use of the parse method returns SybXmlStream. You can use the SybXmlStream return value to query a document using XQL.
  • ·        query(String query, String xmlDoc)queries an XML document where String query is the string you are searching for and String xmldoc is the XML document you are querying. This method returns a Java string.
  • ·        query(String query, InputStream xmlDoc)queries an XML document where String query is the string you’re searching for and InputStream xmlDoc is the XML document you’re querying. Here’s an example:

FileInputStream xmlStream = new FileInputStream(“doc.xml”);
String result = Xql.query(“/bookstore/book/author”, xmlStream);

The following example queries an XML document on the Web using a URL as the search argument:
URL xmlURL = new URL(“http://mywebsite/doc.xml”);
String result = Xql.query(“/bookstore/book/author”, xmlURL.openStream());

The method query(String query, SybXmlStream xmlDoc)queries the XML document using a parsed XML document as the second argument where String query is the string you’re searching for and xmldoc is the parsed XML document you’re querying. The following example illustrates this point:
SybXmlStream xmlStream = Xql.parse(“<xml>..</xml>);
String result = Xql.query(“/bookstore/book/author”,xmlStream);

The method query(String query, JXml jxml) queries an XML document stored in a JXML format where String query is the string you’re searching and JXml jxml is an object created from the classes located in $SYBASE/ASE-12_5/samples/. An example follows:
JXml xDoc = new JXml(“<xml>…</xml>”);;
String result = Xql.query(“/bookstore/book/author”, xDoc);

The static method setParser(String parserName) specifies the parser that the parse method should use. You should make sure that the specified parser class is accessible through the CLASSPATH and is compliant with SAX 2.0. This allows you to set a default parser other than the Xerces 1.3.1 parser that ships with Sybase ASE.

The static method reSetParser() resets the parser to the default parser that Sybase supplies (xerces.jar, Version. 1.3.1).

Tap the power of XQL
You should now have enough of a running start to use XQL on Sybase ASE without too much difficulty. Once you understand both the simplicity and the power of XQL, it’s not nearly as daunting to use as it seems.