Soa 3
Soa 3
Soa 3
XML Processing
WEB service applications often pass information using XML documents. Appli-
cation developers whose applications accept XML documents must understand how
best to extract information from these XML documents and use that information in
their business processing. They must also understand how to assemble XML docu-
ments from the results of this business processing.
This chapter provides an extensive coverage of XML document handling. To
make it more manageable, you may want to concentrate on the sections of particu-
lar interest to you. These sections are as follows:
121
122 XMLOverview
focuses on representing data rather than end-user presentation. While XML aims
to separate data from presentation, the end-user presentation of XML data is nev-
ertheless specifically addressed by additional XML-based technologies in rich and
various ways.
Although XML documents are not primarily intended to be read by users, the
XML specification clearly states as one of its goals that “XML documents should
be human-legible and reasonably clear.” This legibility characteristic contributed
to XML’s adoption. XML supports both computer and human communications,
and it ensures openness, transparency, and platform-independence compared to a
binary format.
A grammar along with its vocabulary (also called a schema in its generic
acception) defines the set of tags and their nesting (the tag structure) that may be
allowed or that are expected in an XML document. In addition, a schema can be
specific to a particular domain, and domain-specific schemas are sometimes
referred to as markup vocabularies. The Document Type Definition (DTD)
syntax, which is part of the core XML specification, allows for the definition of
domain-specific schemas and gives XML its “eXtensible” capability. Over time,
there have been an increasing number of these XML vocabularies or XML-based
languages, and this extensibility is a key factor in XML’s success. In particular,
XML and its vocabularies are becoming the lingua franca of business-to-business
(B2B) communication.
In sum, XML is a metalanguage used to define other markup languages.
While tags help to describe XML documents, they are not sufficient, even when
carefully chosen, to make a document completely self-describing. Schemas
written as DTDs, or in some other schema language such as the W3C XML
Schema Definition (XSD), improve the descriptiveness of XML documents since
they may define a document’s syntax or exact structure. But even with the type
systems introduced by modern schema languages, it is usually necessary to
accompany an XML schema with specification documents that describe the
domain-specific semantics of the various XML tags. These specifications are
intended for application developers and others who create and process the XML
documents. Schemas are necessary for specifying and validating the structure and,
to some extent, the content of XML documents. Even so, developers must ulti-
mately build the XML schema’s tag semantics into the applications that produce
and consume the documents. However, thanks to the well-defined XML markup
scheme, intermediary applications such as document routers can still handle docu-
ments partially or in a generic way without knowing the complete domain-specific
semantics of the documents.
124 XMLOverview
The handling of the following XML document concepts may have a signifi-
cant impact on the design and performance of an XML-based application:
comes an integral part of the document. The logical form is the entire document
regardless of its physical or storage layout.
An XML processor, in the course of processing a document, may need to find
the content of an external entity—this process is called entity resolution. The
XML processor may know some identifying information about the external en-
tity, such as its name, system, or public identifier (in the form of a URI: URL
or URN), and so forth, which it can use to determine the actual location of the
entity. When performing entity resolution, the XML processor maps the
known identifying information to the actual location of the entity. This map-
ping information may be accessible through an entity resolution catalog.
To address these shortcomings, the W3C defined the XML Schema Definition
language (XSD). (XSD became an official recommendation of the W3C in 2001.)
XSD addresses some of the shortcomings of DTD, as do other schema languages,
such as RELAX-NG. In particular, XSD:
The following convention applies to the rest of the chapter: The noun
“schema” or “XML schema” designates the grammar or schema to which an XML
document must conform and is used regardless of the actual schema language
(DTD, XSD, and so forth). Note: While XSD plays a major role in Web services,
Web services may still have to deal with DTD-based schemas because of legacy
reasons.
As an additional convention, we use the word “serialization” to refer to XML
serialization and deserialization. We explicitly refer to Java serialization when
referring to serialization supported by the Java programming language. Also note
that we may use the terms “marshalling” and “unmarshalling” as synonyms for
XML serialization and deserialization. This is the same terminology used by
XML data-binding technologies such as JAXB.
data with the application. It is also possible that these custom schemas may be
publicly exposed. Such custom schemas or application-specific schemas are
defined either from scratch or, if appropriate, they may reuse where possible exist-
ing horizontal or vertical schema components. Note that publishing schemas in
order to share them among partners can be implemented in various ways, includ-
ing publishing the schemas along with Web service descriptions on a registry (see
“Publishing a Web Service” on page 101).
1. Parse and optionally validate the document—Parse and validate the incom-
ing document against the schema to which the document should conform.
2. Transform the document—If necessary, transform the document from its
conforming schema to the internally supported schema.
3. Disassemble the document or pass it as is to the next phase—Disassembling
a document consists of these steps:
■
Search the incoming document for relevant information. The information
can be recognized by using the embedded tags or its expected location within
the document.
■
Extract the relevant information once it is located.
■
Optionally, map the retrieved information to domain-specific objects.
Chapter 4 XML Processing 129
data:ExternalSchema
Transform
data:InternalSchema
Disassemble/ domainSpecificObject
Map
Business
logic
Assemble domainSpecificObject
data:InternalSchema
Transform
data:ExternalSchema
Optionally
doc:ExternalSchema validate then
serialize
Document Emission
Figure 4.1 Activity Diagram Modeling Typical Steps for Handling XML Documents
130 Outline for Handling XML Documents
In the second phase, the application applies the business logic. This entails
actually processing the input information retrieved from the XML document.
Such processing is considered document-centric when the logic handles the docu-
ment directly, or object-centric when the logic is applied to domain-specific
objects to which the retrieved information has been mapped. As a result of this
processing, the application may generate XML output information, which is the
third phase.
The steps for this third phase, XML output processing, mirror that of XML
input processing. Producing XML output consists of the following steps:
Clients, whether a Web service peer or a rich client interacting with an end
user, implement processes, such as the process just presented, for handling XML
documents either submitted along with requests to a service or received as
responses. Sometimes the application logic of human-facing rich clients may have
to deal with the presentation of received documents to the end user rather than
with business logic processing.
Note that real-world enterprise applications may have several instances of this
abstract process to handle documents with unrelated schemas or documents with
unrelated purposes. Moreover, these processes can actually be implemented to
span one or more layers of an enterprise application. In particular, in the case of a
Web service endpoint, these phases can be implemented in both the interaction
and processing layers, depending on the processing model used by the Web ser-
vice. See the discussion on a Web services layered architecture in “Key Web Ser-
vices Design Decisions” on page 61.
type derivation, XML schema design shares many of the aspects of object-oriented
design especially with respect to modularization and reuse.
The design of domain-specific XML schemas breaks down according to the
definition of XML schema types, their relationship to other types, and any con-
straints to which they are subjected. The definitions of such XML schema types,
relationships, and constraints are typically the result of the analysis of the applica-
tion domain vocabulary (also called the business vocabulary). As much as possi-
ble, schema designers should leverage already-defined public vertical domain
schema definitions to promote greater acceptance and interoperability among
intended participants. The designers of new schemas should keep interoperability
concerns in mind and try to account for reuse and extensibility. Figure 4.2 shows
the UML model of a typical XML schema.
anyType
lineItem
categoryId
productId
itemId
lineNo
quantity
unitPrice
decimal
positiveDecimal
Invoice
<X>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="lineItem">
<xsd:attribute name="categoryId" type="xsd:string"
use="required" />
...
<xsd:attribute name="unitPrice" type="positiveDecimal"
use="required" />
134 Designing XML-Based Applications
</xsd:complexType>
<xsd:simpleType name="positiveDecimal">
<xsd:restriction base="xsd:decimal">
<xsd:minInclusive value="0.0" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
sumer of this document to issue many network connections to retrieve these dif-
ferent fragments. Although this sort of modularization and inclusion may lead to
significant network overhead, it does allow consumers of document schemas and
instances to more finely tune caching mechanisms. See “Performance Consider-
ations” on page 182.
Generally, document schema design and the layout of document instances
closely parallel object-oriented design. In addition, design strategies exist that
identify and provide well-defined solutions to common recurring problems in doc-
ument schema design.
Keep the following recommendations in mind when designing an XML
schema:
❐ Adopt and develop design patterns, naming conventions, and other best prac-
tices similar to those used in object-oriented modelling to address the issues of
reuse, modularization, and extensibility.
❐ Leverage existing horizontal schemas, and vertical schemas defined within
your industry, as well as the custom schemas already defined within your en-
terprise.
❐ Do not solely rely on self-describing element and attribute names. Comment
and document custom schemas.
❐ Use modelling tools that support well-known schema languages such as XSD.
Keep in mind that reusing schemas may enable the reuse of the corresponding
XML processing code.
}
}
Code Example 4.2 Sending an XML Document Through a Web Service Client Stub
Code Example 4.3 Receiving an XML Document Through a Web Service Endpoint
public SupplierOrderMDB() {}
There are circumstances when a Web service may internally exchange XML
documents through a JMS queue or topic. When implementing an asynchronous
architecture, the interaction layer of a Web service may send XML documents
asynchronously using JMS to the processing layer. Similarly, when a Web service
implements a workflow, the components implementing the individual stages of
the workflow may exchange XML documents using JMS. From a developer’s
point of view, receiving or sending XML documents through a JMS queue or
topic is similar in principle to the case of passing documents as SOAP message
attachments. XML documents can be passed through a JMS queue or topic as text
messages or in a Java-serialized form when those documents can be bound to Java
objects.
ness—narrow the set of valid document instances to those that the business logic
can effectively process. Regardless of the schema language, even when perform-
ing XML validation, the application is responsible for enforcing any uncovered
domain-specific constraints that the document may nevertheless violate. That is,
the application may have to perform its own business logic-specific validation in
addition to the XML validation.
To decide where and when to validate documents, you may take into account
certain considerations. Assuming a system—by system we mean a set of applica-
tions that compose a solution and that define a boundary within which trusted
components can exchange information—one can enforce validation according to
the following observations. (See Figure 4.3.)
1. Documents exchanged within the components of the system may not require
validation.
2. Documents coming from outside the system, especially when they do not orig-
inate from external trusted sources, must be validated on entry.
3. Documents coming from outside the system, once validated, may be ex-
changed freely between internal components without further validation.
Internet
Intranet
Legend
return false;
}
Code Example 4.7 Setting the Parser for Validation in JAXP 1.2
Chapter 4 XML Processing 143
When relying on the schemas to which documents internally declare they are
conforming (through a DTD declaration or an XSD hint), for security and to avoid
external malicious modification, you should keep your own copy of the schemas
and validate against these copies. This can be done using an entity resolver, which
is an interface from the SAX API (org.xml.sax.EntityResolver), that forcefully
maps references to well-known external schemas to secured copies.
To summarize these recommendations:
Figure 4.4, Figure 4.5, and Figure 4.6 show the sequencing of the activities
involved at design time and the artifacts (schemas and classes) used or produced
by these activities. The figures also show the relationships between these artifacts
and the runtime entities (documents and objects), as well as the interaction at
runtime between these entities.
The first approach (Figure 4.4), which introduces a strong dependency
between the application’s data model and logic and the external schemas, is suit-
able only for applications dedicated to supporting a specific interaction model. A
strong dependency such as this implies that evolving or revising the external
schemas impacts the application’s data model and its logic.
Design time
XML
Schema (1) Design Data
Model Classes Data Model
Classes
Runtime
Figure 4.4 Out-to-In Approach for Mapping Schemas to the Data Model Classes
Chapter 4 XML Processing 145
Design time
(1) Design Inter-
nal XML Schema
Internal XML
Schema
External XML
Schema
(2) Design Style
Sheets Data Model
Classes
Runtime
Transform
Style Sheet
XML
Document Data Model
Adaptation Layer
Objects
schema of the application’s domain. (UBL is an example of the latter case.) The
developer must realize that such an approach has some limitations—it is easier to
transform from a structure containing more information to one with less informa-
tion than the reverse. Therefore, the choice of the generic internal schema is key to
that approach. Code Example 4.8 shows how to use a stylesheet to transform an
external, XSD-based schema to an internal, DTD-based schema.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="http://blueprints.j2ee.sun.com/SupplierOrder"
xmlns:li="http://blueprints.j2ee.sun.com/LineItem"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.0">
<xsl:template match="/">
<SupplierOrder>
<OrderId><xsl:value-of select="/
so:SupplierOrder/so:OrderId" /></OrderId>
<OrderDate><xsl:value-of select="/
so:SupplierOrder/so:OrderDate" /></OrderDate>
<xsl:apply-templates select=".//
so:ShippingAddress|.//li:LineItem"/>
</SupplierOrder>
</xsl:template>
<xsl:template match="/so:SupplierOrder/
so:ShippingAddress">
...
</xsl:template>
<xsl:template match="/so:SupplierOrder/so:LineItems/
li:LineItem">
Chapter 4 XML Processing 147
...
</xsl:template>
</xsl:stylesheet>
Code Example 4.8 Stylesheet for Transforming from External XSD-Based Schema to
Internal DTD-Based Schema
Normally, developers should begin this design process starting from the appli-
cation’s interface definition plus the XML schemas. In some situations, a devel-
oper may have to work in reverse; that is, start from the inside and work out. See
the third approach, shown in Figure 4.6.
Design time
(1) Design XML
Schema
Adapter
Classes
Runtime
Figure 4.6 Legacy Adapter (In-to-Out) Approach for Mapping Schemas to Data
Model Classes
148 Designing XML-Based Applications
The developer may have to use the application’s data model to create a set of
matching schemas, which would then be exposed as part of the application’s inter-
face. This third approach is often used when existing or legacy applications need
to expose an XML-based interface to facilitate a loosely coupled integration in a
broader enterprise system. This technique is also known as legacy adapters or
wrappers. In these cases, the application’s implementation determines the inter-
face and the schemas to expose. In addition, this approach can be combined with
the meet-in-the-middle approach to provide a proper adaptation layer, which in
turn makes available a more interoperable interface that is, an interface that is not
so tightly bound to the legacy application. See Chapter 6 for more information on
application integration.
• A component may not need to know the complete XML document. A compo-
nent may be coded against just a fragment of the overall document schema.
• The document itself may be the persistent core representation of the data mod-
el. Each component maps only portions of the document to transient represen-
tation in order to apply their respective logic and then modifies the document
accordingly.
• Even if the processing model is globally document-centric (see “Choosing Pro-
cessing Models” on page 151), each component can—if adequate—locally im-
plement a more object-centric processing model by mapping portions of the
document to domain-specific objects.
• Each component can handle the document using the most effective or suitable
XML processing technique. (See “Choosing an XML Processing Program-
ming Model” on page 164.)
Chapter 4 XML Processing 149
Account Processing
XML
Workflow Credit Card
Document
Dispatching Processing
Logic
Airline Reservation
Processing
on page 131.) For example, suppose your application works with an Address entity
bean whose instances are initialized with information retrieved from various XML
documents, such as purchase order and invoice documents. Although the XML doc-
uments conform to different schemas, you want to use the same component—the
same Address bean—without modification regardless of the underlying supported
schema.
A good way to address this issue is to design a generic XML schema into
which your component state can be serialized. From this generic schema, you can
generate XML-serializable domain-specific or content objects that handle the seri-
alization of your component state.
EntityBean
AddressBean
XMLSerializable
Address
EntityBean
PurchaseOrderBean
<<XML schema>>
Address.xsd
XMLSerializable
PurchaseOrder
EntityBean
LineItemBean
<<XML schema>>
PurchaseOrder.xsd
XMLSerializable
LineItem
<<XML schema>>
LineItem.xsd
• The schema of the processed documents is only partially known and therefore
cannot be completely bound to domain-specific objects; the application edits
only the known part of the documents before forwarding them for further pro-
cessing.
• Because the schemas of the processed documents may vary or change greatly,
it is not possible to hard-code or generate the binding of the documents to do-
main-specific objects; a more flexible solution is required, such as one using
DOM with XPath.
Account Processing
Airline Reservation
Processing
❐ Rather than pass the entire document to different components handling various
stages of the business process, it’s best if the processing logic breaks the doc-
ument into fragments and passes only the required fragments to other compo-
nents or services that implement portions of the business process logic.
Figure 4.9 shows how the processing layer might process an XML document
representing an incoming purchase order for a travel agency Web service. The
document contains details such as account information, credit card data, travel
destinations, dates, and so forth. The business logic involves verifying the
account, authorizing the credit card, and filling the airline and hotel portions of the
purchase order. It is not necessary to pass all the document details to a business
process stage that is only performing one piece of the business process, such as
account verification. Passing the entire XML document to all stages of the busi-
ness process results in unnecessary information flows and extra processing. It is
more efficient to extract the logical fragments—account fragment, credit card
Chapter 4 XML Processing 155
fragment, and so forth—from the incoming XML document and then pass these
individual fragments to the appropriate business process stages in an appropriate
format (DOM tree, Java object, serialized XML, and so forth) expected by the
receiver.
While it is complementary to most of the mapping design strategies presented
in “Mapping Design Strategies” on page 143, this technique is best compared
against the flexible mapping design strategy. (See “Flexible Mapping” on
page 148.) Flexible mapping advocates a decentralized mapping approach: Com-
ponents or stages in a workflow each handle the complete incoming document,
but each stage only processes the appropriate part of the document. Fragmenting
an incoming document can be viewed as a centralized implementation of the flex-
ible mapping design. Fragmenting an incoming document, by suppressing redun-
dant parsing of the incoming document and limiting the exchanges between stages
to the strictly relevant data, improves performance over a straightforward imple-
mentation of flexible mapping. However, it loses some flexibility because the
workflow dispatching logic is required to specifically know about (and therefore
depend on) the document fragments and formats expected by the different stages.
Fragmenting a document has the following benefits:
• In the interaction layer of a Web service in order to apply some pre- or post-
processing, such as XML validation and transformation to the exchanged doc-
156 Designing XML-Based Applications
design strategies, combined with other strategies for creating factory methods or
abstract factories (strategies for creating new objects where the instantiation of
those objects is deferred to a subclass), to uniformly manipulate documents that
conform to different schemas. The business object can invoke a factory class to
create instances of different XML document editor implementations depending on
the schema of the processed document. This is an alternate approach to applying
transformations for supporting several external schemas.
Interface
XMLDocumentEditor
+setDocument:void
+getDocument:Source
+copyDocument:void
DomainSpecificXDE
BusinessObject Interface
+setDocument:void
uses +getDocument:Source encapsulates javax.xml.trans-
+process:void +copyDocument:void form.Source
+edit:Source +getXXX:
DomainSpecificObject
+setXXX:void
creates, extracts/inserts
obtains/modifies
DomainSpecificObject
assigns/retrieves
Figure 4.10 shows the class diagram for a basic XML document editor design,
while Figure 4.11 shows the class diagram for an XML document editor factory
design. You should consider using a similar design in the following situations:
• When you want to keep the business objects focused on business logic and
keep code to interact with XML documents separate from business logic code.
• In a similar way, when you want to keep the Web service endpoints focused on
interaction logic and keep code to pre- and post-process XML documents sep-
arate from interaction logic code.
Interface
XMLDocumentEditor
XMLDocument
EditorFactory +setDocument:void
+getDocument:Source
+copyDocument:void
creates
obtains
DomainSpecificXDE
BusinessObject Interface
+setDocument:void
uses +getDocument:Source encapsulates javax.xml.trans
+process:void +copyDocument:void form.Source
+edit:Source +getXXX:
DomainSpecificObject
+setXXX:void
creates, extracts/inserts
obtains/modifies
DomainSpecificObject
assigns/retrieves
Figure 4.12 and Code Example 4.9 give an example of a supplier Web service
endpoint using an XML document editor to preprocess incoming purchase order
documents.
Code Example 4.9 Supplier Service Endpoint Using XML Document Editor
Remote
<<interface>>
SupplierService
+submitOrder:String
+queryOrderStatus:String
<<interface>>
XMLDocumentEditor
ServiceLifecycle
+setDocument:void
<<XML schema>> +getDocument:Source
SupplierServiceImpl +copyDocument:void
+init:void
+submitOrder:String
+queryOrderStatus:String
+destroy:void
SupplierOrderXDE
delegates to
-source:Source
-orderid:String
SupplierOrderRcvr
+SupplierOrderXDE
-supplierOrderXDE:SupplierOrderXDE uses
+setDocument:void
-supplierOrderQueueHelper:QueueHelper +setDocument:void
+copyDocument:void
+SupplierOrderRcvr
+getDocument:Source
+receive:String
+getDocumentAsString:String
+getOrderId:String
QueueHelper <<interface>>
-queue:Queue
javax.xml.transform.Source
+QueueHelper
+sendMessage:void
Figure 4.12 Class Diagram of Supplier Service Using XML Document Editor
Chapter 4 XML Processing 163
1. Simple API for XML Parsing (SAX), which provides an event-based program-
ming model
2. Document Object Model (DOM), which provides an in-memory tree-traversal
programming model
3. XML data-binding, which provides an in-memory Java content class-bound
programming model
4. eXtensible Stylesheet Language Transformations (XSLT), which provides a
template-based programming model
The most common processing models are SAX and DOM. These two models
along with XSLT are available through the JAXP APIs. (See “JavaTM APIs for
XML Processing” on page 41.) The XML data binding model is available through
the JAXB technology. (See “Emerging Standards” on page 40.)
Processing an XML document falls into two categories. Not only does it
encompass parsing a source XML document so that the content is available in
some form for an application to process, processing also entails writing or produc-
ing an XML document from content generated by an application. Parsing an XML
representation into an equivalent data structure usable by an application is often
called deserialization, or unmarshalling. Similarly, writing a data structure to an
Chapter 4 XML Processing 165
❐ Just as you would avoid manually parsing XML documents, you should avoid
manually constructing XML documents. It is better to rely on higher-level, re-
liable APIs (such as DOM, and DOM-like APIs, or JAXB technology) to con-
struct XML documents, because these APIs enforce the construction of well-
formed documents. In some instances, these APIs also allow you to validate
constructed XML documents.
1. The application can “on the fly” invoke the business logic on the extracted in-
formation. That is, the logic is invoked as soon as the information is extracted
or after only a minimal consolidation. With this approach, referred to as stream
processing, the document can be processed in one step.
2. The application invokes the business logic after it completes parsing the docu-
ment and has completely consolidated the extracted information. This ap-
proach takes two steps to process a document.
Note that the SAX model may not be the best candidate for application devel-
opers who are more concerned about implementing business logic.
1. The DOM parser creates a tree-like data structure that models the XML source
document. This structure is called a DOM tree.
2. The application code walks the DOM tree, searching for relevant information
that it extracts, consolidates, and processes further. Developers can use consol-
168 Implementing XML-Based Applications
There are limitations to the DOM model. DOM was designed to be both a
platform- and language-neutral interface. Because of this, the Java binding of the
DOM API is not particularly Java friendly. For example, the binding does not use
the java.util.Collection API. Generally, DOM is slightly easier to use than the
SAX model. However, due to the awkwardness of DOM’s Java binding, applica-
tion developers who are focused on the implementation of the business logic may
still find DOM difficult to use effectively. For this reason, similarly with SAX,
application developers should be shielded as much as possible from the DOM
model.
In addition, the DOM API prior to version level 3 does not support serializa-
tion of DOM trees back to XML. Although some implementations do provide
serialization features, these features are not standard. Thus, developers should
instead rely on XSLT identity transformations, which provide a standard way to
achieve serialization back to XML.
Java developers can also use other technologies, such as JDOM and dom4j,
which have similar functionality to DOM. The APIs of these technologies tend to
be more Java-friendly than DOM, plus they interface well with JAXP. They
provide a more elaborate processing model that may alleviate some of DOM’s
inherent problems, such as its high memory usage and the limitation of processing
document content only after a document has been parsed.
Although not yet standard for the Java platform (not until JAXP 1.3), the
Xpath API enables using it in conjunction with the DOM programming model.
(The Xpath API can be found along with some DOM implementations such as
Xerces or dom4j.) Developers use Xpath to locate and extract information from a
source document’s DOM tree. By allowing developers to specify path patterns to
locate element content, attribute values, and subtrees, Xpath not only greatly sim-
plifies, but may even eliminate, tree-traversal code. Since Xpath expressions are
strings, they can be easily parameterized and externalized in a configuration file.
As a result, developers can create more generic or reusable document processing
programs.
Chapter 4 XML Processing 169
To sum up, consider using DOM when any of these circumstances apply:
1. Set up the JAXB context (JAXBContext) with the list of schema-derived pack-
ages that are used to unmarshal the documents.
2. Unmarshal an XML document into a content tree. Validation of the document
is performed if enabled by the application.
3. You can then directly apply the application’s logic to the content tree. Or, you
can extract and consolidate information from the content tree and then apply
the application’s logic on the consolidated information. As described later, this
consolidated information may very well be domain-specific objects that may
expose a more adequate, schema-independent interface.
1. Modify an existing content tree, or create a new tree, from the application’s
business logic output.
2. Optionally, validate in-memory the content tree against the source schema.
Validation is performed in-memory and can be applied independently of the
marshalling process.
3. Marshal the content tree into an XML document.
There are various ways a developer can design an application with the
schema-derived classes that JAXB generates:
1. The developer may use them directly in the business logic, but, as noted in
“Choosing Processing Models” on page 151, this tightly binds the business
logic to the schemas from which the classes were generated. This type of usage
shares most of the issues of a document-centric processing model.
2. The developer can use the schema-derived classes in conjunction with an
object-centric processing model:
a. The developer may design domain-specific classes whose instances will be
populated from the content objects created by unmarshalling an XML
document, and vice versa.
b. The developer may design domain-specific classes, which inherit from the
schema-derived classes, and define additional domain-oriented methods.
The problem with this design is that these classes are tightly coupled to the
Chapter 4 XML Processing 171
❐ You want to deal directly with plain Java objects and do not care about, nor
want to handle, document representation.
❐ You are consuming or producing documents.
❐ You do not need to maintain some aspects of a document, such as comments
and entity references. The JAXB specification does not require giving access
to the underlying document representation (infoset). For example, the JAXB
reference implementation is based on SAX 2.0 and therefore does not maintain
an underlying document representation. However, other implementations may
be layered on top of a DOM representation. A developer may fall back on this
DOM representation to access unexposed infoset elements.
❐ You want to process the content tree more than once.
❐ You want random access to parts of the document. For example, you may want
to traverse back and forth within the document.
❐ Memory usage may be less of an issue. A JAXB implementation, such as the
standard implementation, creates a Java representation of the content of a doc-
ument that is much more compact than the equivalent DOM tree. The standard
172 Implementing XML-Based Applications
implementation is layered on top of SAX 2.0 and does not maintain an addi-
tional underlying representation of the source document. Additionally, where
DOM represents all XML schema numeric types as strings, JAXB’s standard
implementation maps these values directly to much more compact Java numer-
ic data types. Not only does this use less memory to represent the same content,
the JAXB approach saves time, because converting between the two represen-
tations is not necessary.
❐ You previously were implementing XML data-binding manually with DOM,
and an XSD schema definition is available.
By definition, XSLT supports not only processing XML input documents but
it also can output XML documents. (Other output methods include text, HTML,
and so forth.) Note that although the DOM version level 2 API does not support
serialization—that is, transformation of a DOM tree to an XML document—the
JAXP implementation of XSLT addresses the serialization of a DOM tree using
an identity transformer. An identity transformer copies a source tree to a result
tree and applies the specified output method, thus solving the serialization
problem in an easy, implementation-independent manner. For example, to output
in XML, the output method is set to xml. XSLT can also be used to serialize to
XML from DOM trees, SAX events, and so forth.
Consider using XSLT when any of the following circumstances apply:
❐ You want to change the structure, insert, remove, rename, or filter content of
an XML document.
❐ You potentially have more than one transformation for the same document. Al-
though one transformation can be hand coded using another API, multiple
transformations, because of the scripting nature of style sheets, are better done
using XSLT transformations.
❐ You have to perform complex transformations. Because of XSLT’s functional
declarative model, it is easier to design complex transformations by coding in-
dividual rules or templates than by hard-coding procedures.
❐ You want the ability to be flexible and leave room for future changes in the
schemas of documents you are processing.
❐ You want to process documents that contain a significant amount of data to
minimize performance overhead.
❐ You need to transform a document for non-interactive presentation or in batch
mode. The performance overhead of transformation is usually less of an issue
with non-interactive presentations. Such a document might be a purchase order
or an invoice, for example.
❐ You must support multiple external schemas but you want to internally pro-
gram only against a generic schema (schema adapter).
174 Implementing XML-Based Applications
XML
Document
Pipelining
DOM
JAXB
XSLT
SAX
Output
wrappable into a
DOM Tree Content Tree Source
Stream Processing
Business Logic
Random access (in-memory Serial access (flow of events) Random access (in-memory
data structure) using generic using parameters passed to data structure) using Java-
(application independent) events Beans style accessors
API
176 Implementing XML-Based Applications
Table 4.1 DOM, SAX, and XML Data-Binding Programming Models (continued)
High memory usage (The Low memory usage (only Intermediate memory usage
document is often completely events are generated) (The document is often com-
loaded in memory, though pletely loaded in memory, but
some techniques such as the Java representation of the
deferred or lazy DOM node document is more effective
creation may lower the mem- than a DOM representation.
ory usage.) Nevertheless, some imple-
mentations may implement
techniques to lower the mem-
ory usage.)
To edit the document (pro- To process parts of the docu- To edit the document (pro-
cessing the in-memory data ment (handling relevant cessing the in-memory data
structure) events) structure)
To process multiple times To process the document only To process multiple times
(document loaded in once (transient flow of (document loaded in
memory) events) memory)
Processing once the parsing is Stream processing (start pro- Processing once the parsing is
finished cessing before the parsing is finished
finished, and even before the
document is completely read)
• The first design wraps the result of one processing step into a Source object
that can be processed by the next step. XML processing techniques that can
produce an in-memory representation of their results, such as DOM and JAXB,
lend themselves to this design. This design is often called “batch sequential”
because each processing step is relatively independent and each runs to com-
pletion until the next step begins.
• The second design, called “stream processing” or “pipes and filters,” creates a
Chapter 4 XML Processing 177
chain of filters and each filter implements a processing step. XML processing
techniques such as SAX work well with this design.
Code Example 4.10 Combining SAX and XSLT to Perform XML Processing Steps
completely interpreted. (This is especially true if you follow the modular design rec-
ommendations suggested in “Designing Domain-Specific XML Schemas” on
page 131.) In both cases, an XML processor, in the course of processing a document
or a schema, needs to find the content of any external entity to which the document
or schema refers. This process of mapping external entity references to their actual
physical location is called entity resolution. Note that entity resolution recursively
applies to external entity references within parsed external entities.
Entity resolution is particularly critical for managing the XML schemas upon
which your application is based. As noted in “Validating XML Documents” on
page 139, the integrity and the reliability of your application may depend on the
validation of incoming documents against specific schemas—typically the very
same schemas used to initially design your application. Your application usually
cannot afford for these schemas to be modified in any way, whether by malicious
modifications or even legitimate revisions. (For revisions, you should at a
minimum assess the impact of a revision on your application.)
Therefore, you may want to keep your own copies of the schemas underlying
your application and redirect references to these copies. Or you may want to redi-
rect any such references to trusted repositories. A custom entity resolution allows
you to implement the desired mapping of external entity references to actual
trusted physical locations. Moreover, implementing an entity catalog—even as
simple as the one presented in Code Example 4.12—gives you more flexibility for
managing the schemas upon which your application depends. Note that to achieve
our overall goal, the entity catalog must itself be adequately protected. Addition-
ally, redirecting references to local copies of the schemas may improve perfor-
mance when compared to referring to remote copies, especially for remote
references across the Internet. As described in “Reduce the Cost of Referencing
External Entities” on page 189, performance can be improved further by caching
in memory the resolved entities.
Code Example 4.11 illustrates an entity resolver that implements an interface
from the SAX API (org.xml.sax.EntityResolver). The entity resolver uses a
simple entity catalog to map external entity references to actual locations. The
entity catalog is simply implemented as a Properties file that can be loaded from
a URL (see Code Example 4.12). When invoked, this entity resolver first tries to
use the catalog to map the declared public identifier or URI of the external entity
to an actual physical location. If this fails—that is, if no mapping is defined in the
catalog for this public identifier or URI—the entity resolver uses the declared
system identifier or URL of the external entity for its actual physical location. In
both cases, the resolver interprets the actual physical location either as an URL or,
180 Implementing XML-Based Applications
as a fall-back, as a Java resource accessible from the class path of the entity
resolver class. The latter case allows XML schemas to be bundled along with their
dependent XML processing code. Such bundling can be useful when you must
absolutely guarantee the consistency between the XML processing code and the
schemas.
return source;
}
return null;
}
// Maps an external entity URI or Public Identifier to a
// physical location.
public String mapEntityURI(String entityURI) {
return entityCatalog.getProperty(entityURI);
}
DOM may have to load the entire document into memory so that the document
can be edited or data retrieved, whereas SAX allows the document to be processed
as it is parsed. However, despite its initial slowness, it is better to use the DOM
model when the source document must be edited or processed multiple times.
You should also try to use JAXB whenever the document content has a direct
representation, as domain-specific objects, in Java. If you don’t use JAXB, then
you must manually map document content to domain-specific objects, and this
process often (when SAX is too cumbersome to apply—see page 166) requires an
intermediate DOM representation of the document. Not only is this intermediate
DOM representation transient, it consumes memory resources and must be tra-
versed when mapping to the domain-specific objects. With JAXB, you can auto-
matically generate the same code, thus saving development time, and, depending
on the JAXB implementation, it may not create an intermediate DOM representa-
tion of the source document. In any case, JAXB uses less memory resources as a
JAXB content tree is by nature smaller than an equivalent DOM tree.
When using higher-level technologies such as XSLT, keep in mind that they
may rely on lower-level technologies like SAX and DOM, which may affect per-
formance, possibly adversely.
When building complex XML transformation pipelines, use the JAXP class
SAXTransformerFactory to process the results of one style sheet transformation
with another style sheet. You can optimize performance—by avoiding the creation
of in-memory data structures such as DOM trees—by working with SAX events
until at the last stage in the pipeline.
As an alternative, you may consider using APIs other than the four discussed
previously. JDOM and dom4j are particularly appropriate for applications that
implement a document-centric processing model and that must manipulate a
DOM representation of the documents.
JDOM, for example, achieves the same results as DOM but, because it is
more generic, it can address any document model. Not only is it optimized for
Java, but developers find JDOM easy to use because it relies on the Java
Collection API. JDOM documents can be built directly from, and converted to,
SAX events and DOM trees, allowing JDOM to be seamlessly integrated in XML
processing pipelines and in particular as the source or result of XSLT transforma-
tions.
Another alternative API is dom4j, which is similar to JDOM. In addition to
supporting tree-style processing, the dom4j API has built-in support for Xpath.
For example, the org.dom4j.Node interface defines methods to select nodes
according to an Xpath expression. dom4j also implements an event-based pro-
186 PerformanceConsiderations
cessing model so that it can efficiently process large XML documents. When
Xpath expressions are matched during parsing, registered handlers can be called
back, thus allowing you to immediately process and dispose of parts of the docu-
ment without waiting for the entire document to be parsed and loaded into
memory.
When receiving documents through a service endpoint (either a JAX-RPC or
EJB service endpoint) documents are parsed as abstract Source objects. As
already noted, do not assume a specific implementation—StreamSource,
SAXSource, or DOMSource—for an incoming document. Instead, you should ensure
that the optimal API is used to bridge between the specific Source implementation
passed to the endpoint and the intended processing model. Keep in mind that the
JAXP XSLT API does not guarantee that identity transformations are applied in
the most effective way. For example, when applying an identity transformation
from a DOM tree to a DOM tree, the most effective way is to return the source
tree as the result tree without further processing; however, this behavior is not
enforced by the JAXP specification.
A developer may also want to implement stream processing for the applica-
tion so that it can receive the processing requirements as part of the SOAP request
and start processing the document before it is completely received. Document
processing in this manner improves overall performance and is useful when
passing very large documents. Extreme caution should be taken if doing this,
since there is no guarantee that the underlying JAX-RPC implementation will not
wait to receive the complete document before passing the Source object to the
endpoint and that it will effectively pass a Source object that allows for stream
processing, such as StreamSource or SAXSource. The same holds true when imple-
menting stream processing for outgoing documents. While you can pass a Source
object that allows for stream processing, there is no guarantee on how the underly-
ing JAX-RPC implementation will actually handle it.
When you use JAXP, you can later change the underlying parser implementation
without having to change application code.
Internet
Intranet
Legend
In other words, when you are both the producer and consumer of XML docu-
ments, you may use validation as an assertion mechanism during development,
then turn off validation when in production. Additionally, during production vali-
dation can be used as a diagnostic mechanism by setting up validation so that it is
triggered by fault occurrences.
Internet
Intranet
Entity
Schema Resolution
Cache
Repository
Entity
Resolution
Legend
There are two complementary ways to reduce the cost of referencing external
entities:
face. Implementing this interface enables you to retrieve the resources referred
to in the style sheets by the xsl:import or xsl:include statements. For an ap-
plication using a large set of componentized style sheets, this may be used to
implement a cache in much the same way as the EntityResolver. You can use
EntityResolver and URIResolver to implement:
■
A caching mechanism in the application itself, or
■
A custom URI lookup mechanism that may redirect system and public refer-
ences to a local copy of a public repository.
You can use both caching approaches together to ensure even better perfor-
mance. Use a proxy cache for static entities whose lifetime is greater than the
application’s lifetime. This particularly works with public schemas, which include
the version number in their public or system identifier, since they evolve through
successive versions. A custom entity resolver may first map public identifiers
(usually in the form of a URI) into system identifiers (usually in the form of an
URL). Afterwards, it applies the same techniques as a regular cache proxy when
dealing with system identifiers in the form of an URL, especially checking for
updates and avoiding caching dynamic content. Using these caching approaches
often results in a significant performance improvement, especially when external
entities are located on the network. Code Example 4.13 illustrates how to
implement a caching entity resolver using the SAX API.
import java.util.Map;
import java.util.WeakHashMap;
import java.lang.ref.SoftReference;
import org.xml.sax.*;
}
// Attempts to cache an entity; if it’s too big just
// return an input stream to it.
private InputStream cacheEntity(String publicId,
String systemId, InputStream stream) throws IOException {
stream = new BufferedInputStream(stream);
int count = 0;
for (int i = 0; count < buffer.length; count += i) {
if ((i = stream.read(buffer, count,
buffer.length - count)) < 0) { break; }
}
byte[] content = new byte[count];
System.arraycopy(buffer, 0, content, 0, count);
if (count != buffer.length) {
// Cache the entity for future use, using a soft reference
// so that the GC may reclaim it if it’s not referenced
// anymore and memory is running low.
Entity entity = new Entity();
entity.name = publicId != null ? publicId : systemId;
entity.content = content;
entities.put(entity.name, new SoftReference(entity));
return new ByteArrayInputStream(content);
}
// Entity too big to be cached.
return new SequenceInputStream(
new ByteArrayInputStream(content), stream);
}
}
Code Example 4.13 Using SAX API to Implement a Caching Entity Resolver
cache document content (DOM tree or JAXB content tree) in the user’s session on
the interaction or presentation layer to avoid repeatedly invoking the business logic.
However, you quickly consume more memory when you cache the result of a
user request to serve subsequent, related requests. When you take this approach,
keep in mind that it must not be done to the detriment of other users. That is, be
sure that the application does not fail because of a memory shortage caused by
holding the cached results. To help with memory management, use soft refer-
ences, which allow more enhanced interaction with the garbage collector to
implement caches.
When caching a DOM tree in the context of a distributed Web container, the
reference to the tree stored in an HTTP session may have to be declared as
transient. This is because HttpSession requires objects that it stores to be Java
serializable, and not all DOM implementations are Java serializable. Also, Java
serialization of a DOM tree may be very expensive, thus countering the benefits
of caching.
❐ For remote component interaction, Java objects are efficient, serialized XML
—although expensive—may be used for interoperability. DOM is very expen-
sive, and Java serialization of DOM trees is not always supported.
❐ For local component interaction, Java objects are the most efficient and DOM
may be used when required by the application processing model. However, se-
rialized XML is to be avoided.
❐ Bind to domain-specific Java objects as soon as possible and process these ob-
jects rather than XML documents.
196 Conclusion
Table 4.2 Guidelines for Using XML Judiciously for Component Interaction
4.6 Conclusion
This chapter covered much of the considerations a developer should keep in mind
when writing applications, particularly Web services-based applications, that use
XML documents. Once these issues and considerations are understood, then a
developer can make informed decisions about not only how to design and imple-
ment these XML-based applications, but if the applications should even be based on
XML. In a sense, the developer is encouraged to ask this question first: “Should this
application be based on XML?”
Once the developer decides that XML is appropriate for the application, then
the next task is for the developer to design a sound and balanced architecture.
Such an architecture should rely on XML only for what XML is good at. That is,
the architecture should use XML for open, inter-application communication, con-
figuration descriptions, information sharing, and especially for accessing domains
for which public XML schemas exist. At the same time, XML may not be the
appropriate solution of choice when application interfaces are not exposed pub-
licly or for exchanging information between components that should be communi-
cating in a tightly coupled manner.
The chapter also considered the factors a developer must weigh when decid-
ing where and how to perform XML processing. Should XML processing be
limited to the interaction layer of a Web service as a pre- or post-processing stage
of the business logic, or should the business logic itself be expressed in terms of
Chapter 4 XML Processing 197
XML processing? The chapter further helped clarify when it makes sense to
implement an object-centric processing model or a document-centric processing
model.
These decisions determine the developer’s choice among the different XML-
processing APIs and implementations. Furthermore, the chapter described the per-
formance trade-offs among these different processing techniques and compared
performance with functionality and ease of use. It indicated situations where and
why one technique might be superior to another and helped delineate the rationale
for these choices.