Main Page

Previous Section Next Section

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).

To give applications 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. Figure 9.4 summarizes the flow.

Click To expand
Figure 9.4: 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
Start example
<?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@flutebank.com</contacts:work>
         <contacts:personal>john.malkovich@home.com</contacts:personal>
      </contacts:email>
   </contacts:administrator>
</contacts:flutebank>
End example
Listing 9.4b: The schema for the XML document
Start example
<?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 name="flutebank">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="administrator"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="administrator">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="firstname"/>
            <xs:element ref="lastname"/>
            <xs:element ref="telephone"/>
            <xs:element ref="email"/>
         </xs:sequence>
         <xs:attribute name="type" type="xs:string" use="required"/>
         <xs:attribute name="level" type="xs:string" use="required"/>
      </xs:complexType>
   </xs:element>
   <xs:element name="firstname" type="xs:string"/>
   <xs:element name="lastname" type="xs:string"/>
   <xs:element name="telephone">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="pager"/>
            <xs:element ref="cellular"/>>
            <xs:element ref="desk"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="pager" type="xs:string"/>
   <xs:element name="cellular" type="xs:string"/>
   <xs:element name="desk" type="xs:string"/>
   <xs:element name="email">
      <xs:complexType>
         <xs:sequence>
            <xs:element ref="work"/>
            <xs:element ref="personal"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:element name="work" type="xs:string"/>
   <xs:element name="personal" type="xs:string"/>
</xs:schema>
End example
Listing 9.4c: The example from Listing 9.2a modified for schema validation
Start example
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.sun.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.sun.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);
         }
    }
}

End example

Previous Section Next Section


JavaScript Editor Java Tutorials Free JavaScript Editor