Professional XML Development with Apache Tools: Xerces, Xalan, FOP, Cocoon, Axis, Xindice (Wrox Professional Guides)

The XML:DB initiative has defined an abstract API for interacting with an NXD. This API has two parts. A programmatic API lets programs talk to the database. This API serves the same function as the JDBC API: It provides a vendor-neutral API for applications that need to use a database. The initiative also defined an XML vocabulary, XUpdate, for describing updates to be performed on XML data in an NXD. Both the XML:DB API and XUpdate rely on XPath. If you aren’t familiar with XPath (and you ought to be, because it’s so useful), you should skip back to Chapter 2 on Xalan and XSLT; that chapter includes a brief overview of XPath syntax and functionality.

XML:DB

The XML:DB API is broken into a series of modules. These modules are combined to form Core Levels of the API. Because the NXD area is new, and because the required functionality is changing, the authors of the XML:DB API felt that breaking the API into modules was the best way to allow flexibility while providing a guarantee of a particular level of database functionality for a given Core Level. At the moment there are two Core Levels, 0 and 1.

This figure gives an overview of the interfaces defined by XML:DB. The API is designed to be platform neutral, so it’s specified using CORBA IDL types. For our discussion, we’ll look at the Java bindings, but you should know that the intent is for the same API to be used across multiple languages. There are two modules in Core Level 0: API Base and XMLResource.

Core Level 0

The API Base module contains the Configurable, Database, Collection, Resource, ResourceSet, ResourceIterator, and Service interfaces (shown in blue in the previous figure). The XMLResource module contains the XMLResource interface (shown in red). All the interfaces in the API throw XMLDBException to indicate errors. XMLDBException wraps integer error codes in ErrorCodes.

Database

Let’s look at the interfaces in the API Base module. The Database interface is an abstraction of the NXD you want to use. The specification doesn’t specify how you obtain an object that implements Database, so this aspect of using XML:DB is vendor specific and nonportable. Database extends the Configurable interface, which is patterned on the SAX2 Configurable interface, but differs from the SAX version because property values can only be Strings, not Objects. The major functionality of Database is to give you a Collection you can work on. Collections are identified with URIs and can be access-controlled via username and password authentication. Here are the most important methods on Database:

You’ll notice that there are no methods to create/delete collections. These operations must be performed using a collection manager service. We’ll talk more about services in a bit.

DatabaseManager

In the Java implementation of XML:DB, the DatabaseManager class is the glue between the XML:DB interfaces and the database vendors’ implementation of those interfaces. You need to create a DatabaseManager in order to be able to do anything useful with an NXD and the XML:DB APIs. All the methods of DatabaseManager are static:

Collection

Resources in the database are stored in collections, represented by the Collection interface. Collection is where you’ll get access to most of the functionality of an NXD. All the methods for creating, retrieving/querying, updating, and deleting resources are found on Collection. Database vendors can implement the contents of the database as a hierarchy of collections, but this isn’t required (although it may impact your ability to retrieve data, especially if queries can’t traverse child collections). Some of the key methods on Collection are as follows:

Resource

All resources have a String identifier and a type. Resources are the actual containers for data stored within a database. You need a concrete implementation of the Resource interface to do anything useful. The interface identifies a common set of operations:

XMLResource

XMLResource is a specialization of the Resource interface. It adds operations that allow you to put XML data into the resource and get it back out again. The methods of XMLResource don’t deal with XML documents, but rather with either a SAX event stream or a DOM tree:

BinaryResource

BinaryResource is the other specialization of the Resource interface. It allows you to store data as a byte array. It adds no methods to the Resource interface. Instead, it specifies that the getContent and setContent methods are working on byte[] as opposed to Object. When you’re working with a BinaryResource, you should be able to safely downcast the Object arguments and return values of setContent and getContent to byte[].

ResourceSet

We haven’t talked about queries yet; we’ll get to them after we introduce services. But the XML:DB Core Level 0 does include interfaces for dealing with query results. In XML:DB, queries return ResourceSets, which are sets of resources. The name of this interface should really be ResourceList, because the access model for the contents of the ResourceSet is integer indices. This, of course, means that order within the set is important. The other major feature of ResourceSets is that they can produce a ResourceIterator, which you can use to process the contents of the set. Here are the methods on ResourceSet:

ResourceIterator

A ResourceIterator implements the Iterator design pattern. The interface defines Resource-specific methods in the general form of the Java2 collections iterators. We believe the authors of XML:DB wanted to spare the clients of ResourceIterator from having to cast from Object to Resource, so they created a type-specific interface. Unfortunately, it’s one more piece of information that you need to keep around and be aware of. Fortunately, the interface is short and sweet:

Service

The last interface in the API Base is Service, which provides an extension mechanism for collection implementations. Implementations can provide as many or as few services as they wish. The higher levels of the XML:DB Core APIs define some services, and vendors are free to define their own. The Service interface provides a generic interface that all services should provide:

Services also implement the Configurable interface, allowing for customization.

Core Level 1

XML:DB Core Level 1 contains all the functionality in Core Level 0 and adds the XPathQueryService interface.

XPathQueryService

The XPathQueryService provides a query capability for XML:DB. Because it’s defined as a service, there’s room for multiple query capabilities, each implemented as a separate service. You can imagine a more SQL-like query interface, or an XQuery based interface, when the W3C finalizes XQuery as a recommendation. At the moment, though, XPathQueryService is the only query capability for XML:DB-compliant databases.

XPathQueryService gets all of its expressive power from the XPath expression language. In Chapter 2, you saw how XSLT uses XPath to select portions of an XML document. That style of usage is supported by XPathQueryService. One issue with XPath queries is that they rely on namespace prefixes to select nodes belonging to namespaces. XPathQueryService provides a number of methods to set up a group of namespace prefix bindings that are used as the context for any XPath queries executed by the service:

Other Services

At the moment, only Core Levels 0 and 1 are defined by XML:DB. However, the XML:DB initiative has defined a few other services, although they aren’t assigned to any level in the Core API. These services provide facilities for updating and managing collections and for transaction management.

XUpdateQueryService

The XUpdateQueryService allows you to execute XUpdate commands against a collection or a resource in a collection. We’ll cover the details of XUpdate in the next section. For now, you need to know that XUpdate commands take the form of an XML document:

CollectionManagementService

The CollectionManagementService provides the facilities you need to create and remove collections:

TransactionService

XML:DB defines a TransactionService to allow basic transaction capabilities. These capabilities allow you to mark transaction boundaries and control transaction commit and abort:

The current release of Xindice doesn’t support the transaction service, but it does support all the other API’s that we’ve discussed in this section.

XUpdate

The XML:DB initiative has defined XUpdate, an XML vocabulary that specifies how to update all or part of an XML document. In the context of an XML:DB database, XUpdate documents are used as commands to the XUpdateQueryService; but XUpdate is useful any time you need to describe an update to an XML document. XUpdate relies on XPath for selecting the parts of the document to be updated and uses XPath expressions for conditional processing of updates. XUpdate is broken into two pieces: a set of elements for describing the contents of the update operation and a set of attributes for describing the kind of update operation that should be performed. For the examples in this section, we’ll return to the simple inventory of books (books.xml):

1: <?xml version="1.0" encoding="UTF-8"?> 2: <books xmlns="http://sauria.com/schemas/apache-xml-book/books" 3: xmlns:tns="http://sauria.com/schemas/apache-xml-book/books" 4: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5: xsi:schemaLocation= 6: "http://sauria.com/schemas/apache-xml-book/books 7: http://www.sauria.com/schemas/apache-xml-book/books.xsd" 8: version="1.0"> 9: <book> 10: <title>Professional XML Development with Apache Tools</title> 11: <author>Theodore W. Leung</author> 12: <isbn>0-7645-4355-5</isbn> 13: <month>December</month> 14: <year>2003</year> 15: <publisher>Wrox</publisher> 16: <address>Indianapolis, Indiana</address> 17: </book> 18: <book> 19: <title>Effective Java</title> 20: <author>Joshua Bloch</author> 21: <isbn>0-201-31005-8</isbn> 22: <month>August</month> 23: <year>2001</year> 24: <publisher>Addison-Wesley</publisher> 25: <address>New York, New York</address> 26: </book> 27: <book> 28: <title>Design Patterns</title> 29: <author>Erich Gamma</author> 30: <author>Richard Helm</author> 31: <author>Ralph Johnson</author> 32: <author>John Vlissides</author> 33: <isbn>0-201-63361-2</isbn> 34: <month>October</month> 35: <year>1994</year> 36: <publisher>Addison-Wesley</publisher> 37: <address>Reading, Massachusetts</address> 38: </book> 39: </books>

Update Contents

XUpdate provides elements for creating elements, attributes, and processing constructions with computed names. It also provides elements for creating text and comments, so that all the major components of XML documents can be created and used for updates:

Update Operations

Now that you can construct fragments of XML documents, you can use those fragments to update the contents of a document in the database. An XUpdate update consists of an <xupdate:modifications> element that contains one or more of the following update command elements:

Let’s look at a few examples of how this works. We’ll take the earlier book inventory and apply a few XUpdates to it to see what we get. Apply this insert-before:

1: <?xml version="1.0"?> 2: <xupdate:modifications version="1.0" 3: xmlns:xupdate="http://www.xmldb.org/xupdate"> 4: <xupdate:insert-after 5: select='/tns:books/tns:book[tns:title="Effective Java"]'> 6: <xupdate:element name="book"> 7: <title>Refactoring</title> 8: <author>Martin Fowler</author> 9: <isbn>0-201-48567-2</isbn> 10: <month>September</month> 11: <year>2000</year> 12: <publisher>Addison-Wesley</publisher> 13: <address>Reading, Massachusetts</address> 14: <xupdate:comment>Added 8/2003</xupdate:comment> 15: </xupdate:element> 16: </xupdate:insert-after> 17: </xupdate:modifications>

Your document looks like this:

1: <?xml version="1.0"?> 2: <books xmlns="http://sauria.com/schemas/apache-xml-book/books" 3: xmlns:tns="http://sauria.com/schemas/apache-xml-book/books" 4: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5: xsi:schemaLocation=" 6: http://sauria.com/schemas/apache-xml-book/books 7: http://www.sauria.com/schemas/apache-xml-book/books.xsd" 8: version="1.0"> 9: <book> 10: <title>Professional XML Development with Apache Tools</title> 11: <author>Theodore W. Leung</author> 12: <isbn>0-7645-4355-5</isbn> 13: <month>December</month> 14: <year>2003</year> 15: <publisher>Wrox</publisher> 16: <address>Indianapolis, Indiana</address> 17: </book> 18: <book> 19: <title>Effective Java</title> 20: <author>Joshua Bloch</author> 21: <isbn>0-201-31005-8</isbn> 22: <month>August</month> 23: <year>2001</year> 24: <publisher>Addison-Wesley</publisher> 25: <address>New York, New York</address> 26: </book> 27: <book> 28: <title>Refactoring</title> 29: <author>Martin Fowler</author> 30: <isbn>0-201-48567-2</isbn> 31: <month>September</month> 32: <year>2000</year> 33: <publisher>Addison-Wesley</publisher> 34: <address>Reading, Massachusetts</address> 35: <!--Added 8/2003--> 36: </book> 37: <book> 38: <title>Design Patterns</title> 39: <author>Erich Gamma</author> 40: <author>Richard Helm</author> 41: <author>Ralph Johnson</author> 42: <author>John Vlissides</author> 43: <isbn>0-201-63361-2</isbn> 44: <month>October</month> 45: <year>1994</year> 46: <publisher>Addison-Wesley</publisher> 47: <address>Reading, Massachusetts</address> 48: </book> 49: </books>

Here is an XUpdate document which renames the books element to book-inventory.

1: <?xml version="1.0"?> 2: <xupdate:modifications version="1.0" 3: xmlns:xupdate="http://www.xmldb.org/xupdate"> 4: <xupdate:rename select="/tns:books">book-inventory</xupdate:rename> 5: </xupdate:modifications>

The updated document looks like this:

1: <?xml version="1.0"?> 2: <book-inventory 3: xmlns="http://sauria.com/schemas/apache-xml-book/books" 4: xmlns:tns="http://sauria.com/schemas/apache-xml-book/books" 5: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6: xsi:schemaLocation=" 7: http://sauria.com/schemas/apache-xml-book/books 8: http://www.sauria.com/schemas/apache-xml-book/books.xsd" 9: version="1.0"> 10: <book> 11: <title>Professional XML Development with Apache Tools</title> 12: <author>Theodore W. Leung</author> 13: <isbn>0-7645-4355-5</isbn> 14: <month>December</month> 15: <year>2003</year> 16: <publisher>Wrox</publisher> 17: <address>Indianapolis, Indiana</address> 18: </book> 19: <book> 20: <title>Effective Java</title> 21: <author>Joshua Bloch</author> 22: <isbn>0-201-31005-8</isbn> 23: <month>August</month> 24: <year>2001</year> 25: <publisher>Addison-Wesley</publisher> 26: <address>New York, New York</address> 27: </book> 28: <book> 29: <title>Refactoring</title> 30: <author>Martin Fowler</author> 31: <isbn>0-201-48567-2</isbn> 32: <month>September</month> 33: <year>2000</year> 34: <publisher>Addison-Wesley</publisher> 35: <address>Reading, Massachusetts</address> 36: <!--Added 8/2003--> 37: </book> 38: <book> 39: <title>Design Patterns</title> 40: <author>Erich Gamma</author> 41: <author>Richard Helm</author> 42: <author>Ralph Johnson</author> 43: <author>John Vlissides</author> 44: <isbn>0-201-63361-2</isbn> 45: <month>October</month> 46: <year>1994</year> 47: <publisher>Addison-Wesley</publisher> 48: <address>Reading, Massachusetts</address> 49: </book> 50: </book-inventory>

Категории