JaVa
   

JAXP and XML Schemas

An XML document can optionally be associated with the XML schema or a DTD defining its structure. While parsing the document with SAX, a DTD, as mentioned earlier, can be parsed and then validated using the DTDHandler. A special handler like a DTDHandler is needed is because DTDs are not XML documents.

With Web services, XML schemas are a preferred mechanism for defining the data. Details about DTDs, schemas, and namespaces can be found in Appendix A. Let us now look at how JAXP works for validating XML against the schema. JAXP 1.1 did not expose any schema-related functionality at the API level. It was up to the implementation to support schema validation (the Xerces-j parsers or the reference implementation did validate schemas when validation and namespace processing were enabled). Even though a schema may be associated with an XML document, the W3C recommendations on validating the document against schemas do not mandate a particular mechanism for actually locating the schemas. This makes sense, because there might be cases where the schemas are already available and known (e.g., under business agreements between business partners), or such validation may never be feasable (e.g., XML parsing on J2ME devices).

Java Start Sidebar

The W3C recommendation on schemas states that the xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes serve only to provide hints to the parser about the the physical location of schema documents. They do not mandate that these attributes be used to locate the schemas. However most parsers use these attributes effectively. See Appendix A for details.

Java End Sidebar

To give apps flexibility and to follow the suggested W3C recommendations, JAXP 1.2 introduces two additional properties that can be passed to the SAXParser using the setProperty() method and to DocumentBuilderFactory using the setAttribute() method:

JAXP behavior for parsing and validating schemas with these properties is in line with the W3C recommendation. Screenshot summarizes the flow.

Java Click To expand
Screenshot: XML validation with JAXP 1.2

Let us look at an example of validating XML based on its schema. Listing 9.4a shows the XML from Listing 9.1 with a schema associated with it. Listing 9.4b shows the schema itself. Listing 9.4c shows the code required to validate the schema against the XML document. It differs from the previous code only in that the properties have been set and the factory told to return a namespace-aware, validating parser.

Listing 9.4a: XML document with schema and namespaces
<?xml version="1.0"?>
<contacts:flutebank xmlns="http://www.flutebank.com/schema" xmlns:xsi="http://
www.w3.org/2001/XMLSchema-instance" xmlns:contacts="http://www.flutebank.com/schema"
xsi:schemaLocation="http://www.flutebank.com/schema saxexample2.xsd">
 <contacts:administrator type="maintenance" level="support-1">
 <contacts:firstname>John</contacts:firstname>
 <contacts:lastname> Malkovich</contacts:lastname>
 <contacts:telephone>
 <contacts:pager>783-393-9213</contacts:pager>
 <contacts:cellular>379-234-2342</contacts:cellular>
 <contacts:desk>322-324-2349</contacts:desk>
 </contacts:telephone>
 <contacts:email>
 <contacts:work>john.malkovich@bugmenot.com</contacts:work>
 <contacts:personal>john.malkovich@bugmenot.com</contacts:personal>
 </contacts:email>
 </contacts:administrator>
</contacts:flutebank>



Java End example
Listing 9.4b: The schema for the XML document
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.flutebank.com/schema" xmlns="http://
www.flutebank.com/schema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
 <xs:element >
 <xs:complexType>
 <xs:sequence>
 <xs:element ref="administrator"/>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
 <xs:element >
 <xs:complexType>
 <xs:sequence>
 <xs:element ref="firstname"/>
 <xs:element ref="lastname"/>
 <xs:element ref="telephone"/>
 <xs:element ref="email"/>
 </xs:sequence>
 <xs:attribute type="xs:string" use="required"/>
 <xs:attribute type="xs:string" use="required"/>
 </xs:complexType>
 </xs:element>
 <xs:element type="xs:string"/>
 <xs:element type="xs:string"/>
 <xs:element >
 <xs:complexType>
 <xs:sequence>
 <xs:element ref="pager"/>
 <xs:element ref="cellular"/>>
 <xs:element ref="desk"/>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
 <xs:element type="xs:string"/>
 <xs:element type="xs:string"/>
 <xs:element type="xs:string"/>
 <xs:element >
 <xs:complexType>
 <xs:sequence>
 <xs:element ref="work"/>
 <xs:element ref="personal"/>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
 <xs:element type="xs:string"/>
 <xs:element type="xs:string"/>
</xs:schema>



Java End example
Listing 9.4c: The example from Listing 9.2a modified for schema validation
public class SAXParsingWithSchemas {
 public static void main(String[] arg) {
 try {
 // Create a new factory that will create the parser.
 SAXParserFactory factory = SAXParserFactory.newInstance();
 factory.setNamespaceAware(true);
 factory.setValidating(true);
 SAXParser parser = factory.newSAXParser();
 parser.setProperty("http://java.oracle.com/xml/jaxp/properties/schemaLanguage",
 "http://www.w3.org/2001/XMLSchema");
// If needed the schema source can be set explicitly as shown below. This example uses
// the schema associated with the XML document
// parser.setProperty("http://java.oracle.com/xml/jaxp/properties/schemaSource",
// , new InputSource(someuri));
 DefaultHandler handler = new MySAXHandler();
 parser.parse( new File(filename), handler);
 } catch (Exception e) {
 System.out.println(e);
 }
 }
}



Java End example

JaVa
Comments