Oracle® XML Developer's Kit Programmer's Guide 10g Release 2 (10.2) Part Number B14252-01 |
|
|
View PDF |
This chapter contains these topics:
This section describes the different techniques for XML validation. It discusses the following topics:
This chapter assumes that you have working knowledge of the following technologies:
Document Type Definition (DTD). An XML DTD defines the legal structure of an XML document.
XML Schema language. XML Schema defines the legal structure of an XML document.
If you are unfamiliar with these technologies or need to refresh your knowledge, you can consult the XML resources in "Related Documents" of the preface.
See Also:
|
XML Schema is a W3C standard. You can find the XML Schema specifications at the following locations:
http://www.w3.org/TR/xmlschema-0/
for the W3C XML Schema Primer
http://www.w3.org/TR/xmlschema-1/
for the definition of the XML Schema language structures
http://www.w3.org/TR/xmlschema-2/
for the definition of the XML Schema language datatypes
The Oracle XML Schema processor supports the W3C XML Schema specifications.
DTDs were originally developed for SGML. XML DTDs are a subset of those available in SGML and provide a mechanism for declaring constraints on XML markup. XML DTDs enable the specification of the following:
Which elements can be in your XML documents
The content model of an XML element, that is, whether the element contains only data or has a set of subelements that defines its structure. DTDs can define whether a subelement is optional or mandatory and whether it can occur only once or multiple times.
Attributes of XML elements. DTDs can also specify whether attributes are optional or mandatory.
Entities that are legal in your XML documents.
An XML DTD is not itself written in XML, but is a context-independent grammar for defining the structure of an XML document. You can declare a DTD in an XML document itself or in a separate file from the XML document.
Validation is the process by which you verify an XML document against its associated DTD, ensuring that the structure, use of elements, and use of attributes are consistent with the definitions in the DTD. Thus, applications that handle XML documents can assume that the data matches the definition.
By using the XDK, you can write an application that includes a validating XML parser, that is, a program that parses and validates XML documents against a DTD. Note the following aspects of parsers that perform DTD validation:
Depending on its implementation, a validating parser may stop processing when it encounters an error, or continue.
A validating parser may report warnings and errors as they occur as in summary form at the end of processing.
Most processors can enable or disable validation mode, but they must still process entity definitions and other constructs of DTDs.
Example 5-1 shows the contents of a DTD named family.dtd
, which is located in $ORACLE_HOME/xdk/demo/java/parser/common/
. The <ELEMENT>
tags specify the legal nomenclature and structure of elements in the document, whereas the <ATTLIST>
tags specify the legal attributes of elements.
Example 5-1 family.dtd
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT family (member*)> <!ATTLIST family lastname CDATA #REQUIRED> <!ELEMENT member (#PCDATA)> <!ATTLIST member memberid ID #REQUIRED> <!ATTLIST member dad IDREF #IMPLIED> <!ATTLIST member mom IDREF #IMPLIED>
Example 5-2 shows the contents of an XML document named family.xml
, which is also located in $ORACLE_HOME/xdk/demo/java/parser/common/
. The <!DOCTYPE>
element in family.xml
specifies that this XML document conforms to the external DTD named family.dtd
.
Example 5-2 family.xml
<?xml version="1.0" standalone="no"?> <!DOCTYPE family SYSTEM "family.dtd"> <family lastname="Smith"> <member memberid="m1">Sarah</member> <member memberid="m2">Bob</member> <member memberid="m3" mom="m1" dad="m2">Joanne</member> <member memberid="m4" mom="m1" dad="m2">Jim</member> </family>
The XML Schema language, also known as XML Schema Definition, was created by the W3C to use XML syntax to describe the content and the structure of XML documents. An XML schema is an XML document written in the XML Schema language. An XML schema document contains rules describing the structure of an input XML document, called an instance document. An instance document is valid if and only if it conforms to the rules of the XML schema.
The XML Schema language defines such things as the following:
Which elements and attributes are legal in the instance document
Which elements can be children of other elements
The order and number of child elements
Datatypes for elements and attributes
Default and fixed values for elements and attributes
A validating XML parser tries to determine whether an instance document conforms to the rules of its associated XML schema. By using the XDK, you can write a validating parser that performs this schema validation. Note the following aspects of parsers that perform schema validation:
Depending on its implementation, the parser may stop processing when it encounters an error, or continue.
The parser may report warnings and errors as they occur as in summary form at the end of processing.
The processor must take into account entity definitions and other constructs that are defined in a DTD that is included by the instance document. The XML Schema language does not define what must occurs when an instance document includes both an XML schema and a DTD. Thus, the behavior of the application in such cases depends on the implementation.
Example 5-3 shows a sample XML document that contains a purchase report that describes the parts that have been ordered in different regions. This sample file is located at $ORACLE_HOME/xdk/demo/java/schema/report.xml
.
Example 5-3 report.xml
<purchaseReport xmlns="http://www.example.com/Report" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/Report report.xsd" period="P3M" periodEnding="1999-12-31"> <regions> <zip code="95819"> <part number="872-AA" quantity="1"/> <part number="926-AA" quantity="1"/> <part number="833-AA" quantity="1"/> <part number="455-BX" quantity="1"/> </zip> <zip code="63143"> <part number="455-BX" quantity="4"/> </zip> </regions> <parts> <part number="872-AA">Lawnmower</part> <part number="926-AA">Baby Monitor</part> <part number="833-AA">Lapis Necklace</part> <part number="455-BX">Sturdy Shelves</part> </parts> </purchaseReport>
Example 5-4 shows the XML schema document named report.xsd
, which is the sample XML schema document that you can use to validate report.xml
. Among other things, the XML schema defines the names of the elements that are legal in the instance document as well as the type of data that the elements can contain.
Example 5-4 report.xsd
<schema targetNamespace="http://www.example.com/Report" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:r="http://www.example.com/Report" elementFormDefault="qualified"> <annotation> <documentation xml:lang="en"> Report schema for Example.com Copyright 2000 Example.com. All rights reserved. </documentation> </annotation> <element name="purchaseReport"> <complexType> <sequence> <element name="regions" type="r:RegionsType"> <keyref name="dummy2" refer="r:pNumKey"> <selector xpath="r:zip/r:part"/> <field xpath="@number"/> </keyref> </element> <element name="parts" type="r:PartsType"/> </sequence> <attribute name="period" type="duration"/> <attribute name="periodEnding" type="date"/> </complexType> <unique name="dummy1"> <selector xpath="r:regions/r:zip"/> <field xpath="@code"/> </unique> <key name="pNumKey"> <selector xpath="r:parts/r:part"/> <field xpath="@number"/> </key> </element> <complexType name="RegionsType"> <sequence> <element name="zip" maxOccurs="unbounded"> <complexType> <sequence> <element name="part" maxOccurs="unbounded"> <complexType> <complexContent> <restriction base="anyType"> <attribute name="number" type="r:SKU"/> <attribute name="quantity" type="positiveInteger"/> </restriction> </complexContent> </complexType> </element> </sequence> <attribute name="code" type="positiveInteger"/> </complexType> </element> </sequence> </complexType> <simpleType name="SKU"> <restriction base="string"> <pattern value="\d{3}-[A-Z]{2}"/> </restriction> </simpleType> <complexType name="PartsType"> <sequence> <element name="part" maxOccurs="unbounded"> <complexType> <simpleContent> <extension base="string"> <attribute name="number" type="r:SKU"/> </extension> </simpleContent> </complexType> </element> </sequence> </complexType> </schema>
The XML Schema language includes most of the capabilities of the DTD specification. An XML schema serves a similar purpose to a DTD, but is more flexible in specifying document constraints. Table 5-1 compares some of the features between the two validation mechanisms.
Table 5-1 Feature Comparison Between XML Schema and DTD
Feature | XML Schema | DTD |
---|---|---|
Element nesting | X | X |
Element occurrence constraints | X | X |
Permitted attributes | X | X |
Attribute types and default values | X | X |
Written in XML | X | |
Namespace support | X | |
Built-In datatypes | X | |
User-Defined datatypes | X | |
Include/Import | X | |
Refinement (inheritance) | X |
The following reasons are probably the most persuasive for choosing XML schema validation over DTD validation:
The XML Schema language enables you to define rules for the content of elements and attributes. You achieve control over content by using datatypes. With XML Schema datatypes you can more easily perform actions such as the following:
Declare which elements should contain which types of data, for example, positive integers in one element and years in another
Process data obtained from a database
Define restrictions on data, for example, a number between 10 and 20
Define data formats, for example, dates in the form MM-DD-YYYY
Convert data between different datatypes, for example, strings to dates
Unlike DTD grammar, documents written in the XML Schema language are themselves written in XML. Thus, you can perform the following actions:
Use your XML parser to parse your XML schema
Process your XML schema with the XML DOM
Transform your XML document with XSLT
Reuse your XML schemas in other XML schemas
Extend your XML schema by adding elements and attributes
Reference multiple XML schemas from the same document
The Oracle XML Schema processor is a SAX-based XML schema validator that you can use to validate instance documents against an XML schema. The processor supports both LAX and strict validation.
You can use the processor in the following ways:
Enable it in the XML parser
Use it with a DOM tree to validate whole or part of an XML document
Use it as a component in a processing pipeline (like a content handler)
You can configure the schema processor in different ways depending on your requirements. For example, you can do the following:
Use a fixed XML schema or automatically build a schema based on the schemaLocation
attributes in an instance document.
Set XMLError
and entityResolver
to gain better control over the validation process.
Determine how much of an instance document should be validated. You can use any of the validation modes specified in Table 3-1. You can also designate a type of element as the root of validation.
The following XDK packages are important for applications that process XML schemas:
oracle.xml.parser.v2
, which provides APIs for XML parsing
oracle.xml.parser.schema
, which provides APIs for XML Schema processing
The most important classes in the oracle.xml.parser.schema
package are described in Table 5-2. These form the core of most XML schema applications.
Table 5-2 oracle.xml.parser.schema Classes
Class/Interface | Description | Methods |
---|---|---|
XMLSchema class |
Represents XML Schema component model. An XMLSchema object is a set of XMLSchemaNodes that belong to different target namespaces. The XSDValidator class uses XMLSchema for schema validation or metadata. |
The principal methods are as follows:
|
XMLSchemaNode class |
Represents schema components in a target namespace, including type definitions, element and attribute delcarations, and group and attribute group definitions. | The principal methods are get methods such as getElementSet() and getAttributeDeclarations() obtain components of the XML schema. |
XSDBuilder class |
Builds an XMLSchema object from an XML schema document. The XMLSchema object is a set of objects (Infoset items) corresponding to top-level schema declarations and definitions. The schema document is XML parsed and converted to a DOM tree. |
The principal methods are as follows:
|
XSDValidator class |
Validates an instance XML document against an XML schema. When registered, an XSDValidator object is inserted as a pipeline node between XMLParser and XMLDocument events handlers. |
The principal methods are as follows:
|
Figure 5-1 depicts the basic process of validating an instance document with the XML Schema processor.
The XML Schema processor performs the following major tasks:
A builder (XSDBuilder
object) assembles the XML schema from an input XML schema document. Although instance documents and schemas need not exist specifically as files on the operating system, they are commonly referred to as files. They may exist as streams of bytes, fields in a database record, or collections of XML Infoset "Information Items."
This task involves parsing the schema document into an object. The builder creates the schema object explicitly or implicitly:
In explicit mode, you pass in an XML schema when you invoke the processor. "Validating Against Externally Referenced XML Schemas" explains how to build the schema object in explicit mode.
In implicit mode, you do not pass in an XML schema when you invoke the processor because the schema is internally referenced by the instance document. "Validating Against Internally Referenced XML Schemas" explains how to create the schema object in implicit mode.
The XML schema validator uses the schema object to validate the instance document. This task involves the following steps:
A SAX parser parses the instance document into SAX events, which it passes to the validator.
The validator receives SAX events as input and validates them against the schema object, sending an error message if it finds invalid XML components.
"Validation in the XML Parser" describes the validation modes that you can use when validating the instance document. If you do not explicitly set a schema for validation with the XSDBuilder
class, then the instance document must have the correct xsi:schemaLocation
attribute pointing to the schema file. Otherwise, the program will not perform the validation. If the processor encounters errors, it generates error messages.
The validator sends input SAX events, default values, or post-schema validation information to a DOM builder or application.
See Also:
|
Demo programs for the XML Schema processor for Java are included in $ORACLE_HOME/xdk/demo/java/schema
. Table 5-3 describes the XML files and programs that you can use to test the XML Schema processor.
Table 5-3 XML Schema Sample Files
File | Description |
---|---|
cat.xsd |
A sample XML schema used by the XSDSetSchema.java program to validate catalogue.xml . The cat.xsd schema specifies the structure of a catalogue of books. |
catalogue.xml |
A sample instance document that the XSDSetSchema.java program uses to validate against the cat.xsd schema. |
catalogue_e.xml |
A sample instance document used by the XSDSample.java program. When the program tries to validate this document against the cat.xsd schema, it generates schema errors. |
DTD2Schema.java |
This sample program converts a DTD (first argument) into an XML Schema and uses it to validate an XML file (second argument). |
embeded_xsql.xsd |
The XML schema used by XSDLax.java. The schema defines the structure of an XSQL page. |
embeded_xsql.xml |
The instance document used by XSDLax.java . |
juicer1.xml |
A sample XML document for use with xsdproperty.java . The XML schema that defines this document is juicer1.xsd . |
juicer1.xsd |
A sample XML schema for use with xsdproperty.java . This XML schema defines juicer1.xml . |
juicer2.xml |
A sample XML document for use with xsdproperty.java . The XML schema that defines this document is juicer2.xsd . |
juicer2.xsd |
A sample XML document for use with xsdproperty.java . This XML schema defines juicer2.xml . |
report.xml |
The sample XML file that XSDSetSchema.java uses to validate against the XML schema report.xsd . |
report.xsd |
A sample XML schema used by the XSDSetSchema.java program to validate the contents of report.xml . The report.xsd schema specifies the structure of a purchase order. |
report_e.xml |
When the program validates this sample XML file using XSDSample.java , it generates XML Schema errors. |
xsddom.java |
This program shows how to validate an instance document by obtain a DOM representation of the document and using an XSDValidator object to validate it. |
xsdent.java |
This program validates an XML document by redirecting the referenced schema in the SchemaLocation attribute to a local version. |
xsdent.xml |
This XML document describes a book. The file is used as an input to xsdent.java . |
xsdent.xsd |
This XML schema document defines the rules for xsdent.xml . The schema document contains a schemaLocation attribute set to xsdent-1.xsd . |
xsdent-1.xsd |
The XML schema document referenced by the schemaLocation attribute in xsdent.xsd . |
xsdproperty.java |
This demo shows how to configure the XML Schema processor to validate an XML document based on a complex type or element declaration. |
xsdsax.java |
This demo shows how to validate an XML document received as a SAX stream. |
XSDLax.java |
This demo is the same as XSDSetSchema.java but sets the SCHEMA_LAX_VALIDATION flag for LAX validation. |
XSDSample.java |
This program is a sample driver that you can use to process XML instance documents. |
XSDSetSchema.java |
This program is a sample driver to process XML instance documents by overriding the schemaLocation . The program uses the XML Schema specification from cat.xsd to validate the contents of catalogue.xml . |
Documentation for how to compile and run the sample programs is located in the README
in the same directory. The basic steps are as follows:
Change into the $ORACLE_HOME/xdk/demo/java/schema
directory (UNIX) or %ORACLE_HOME%\xdk\demo\java\schema
directory (Windows).
Run make
(UNIX) or Make.bat
(Windows) at the command line.
Add xmlparserv2.jar
, xschema.jar
, and the current directory to the CLASSPATH
. These JAR files are located in $ORACLE_HOME/lib
(UNIX) and %ORACLE_HOME%\lib
(Windows). For example, you can set the CLASSPATH
as follows with the tcsh
shell on UNIX:
setenv CLASSPATH "$CLASSPATH":$ORACLE_HOME/lib/xmlparserv2.jar:$ORACLE_HOME/lib/schema.jar:.
Note that the XML Schema processor requires JDK version 1.2 or higher and is usable on any operating system with Java 1.2 support.
Run the sample programs with the XML files that are included in the directory:
The following examples use report.xsd
to validate the contents of report.xml
:
java XSDSample report.xml java XSDSetSchema report.xsd report.xml
The following example validates an instance document in Lax mode:
java XSDLax embeded_xsql.xsd embeded_xsql.xml
The following examples use cat.xsd
to validate the contents of catalogue.xml
:
java XSDSample catalogue.xml java XSDSetSchema cat.xsd catalogue.xml
The following examples generates error messages:
java XSDSample catalogue_e.xml java XSDSample report_e.xml
The following example uses the schemaLocation
attribute in xsdent.xsd
to redirect the XML schema to xsdent-1.xsd
for validation:
java xsdent xsdent.xml xsdent.xsd
The following example generates a SAX stream from report.xml
and validates it against the XML schema defined in report.xsd
:
java xsdsax report.xsd report.xml
The following example creates a DOM representation of report.xml
and validates it against the XML schema defined in report.xsd
:
java xsddom report.xsd report.xml
The following examples configure validation starting with an element declaration or complex type definition:
java xsdproperty juicer1.xml juicer1.xsd http://www.juicers.org \ juicersType false > juicersType.out java xsdproperty juicer2.xml juicer2.xsd http://www.juicers.org \ Juicers true > juicers_e.out
The following example converts a DTD (dtd2schema.dtd
) into an XML schema and uses it to validate an instance document (dtd2schema.xml
):
java DTD2Schema dtd2schema.dtd dtd2schema.xml
"Using the XML Parser Command-Line Utility" describes how to run the oraxml
command-line utility. You can use this utility to validate instance documents against XML schemas and DTDs.
Change into the $ORACLE_HOME/xdk/demo/java/schema
directory. Example 5-5 shows how you can validate report.xml
against report.xsd
by executing the following on the command line.
You should obtain the following output:
The encoding of the input file: UTF-8The input XML file is parsed without errors using Schema validation mode.
Change into the $ORACLE_HOME/xdk/demo/java/parser/common
directory. Example 5-6 shows how you can validate family.xml
against family.dtd
by executing the following on the command line.
You should obtain the following output:
The encoding of the input file: UTF-8 The input XML file is parsed without errors using DTD validation mode.
This section includes the following topics:
The $ORACLE_HOME/xdk/demo/java/schema/XSDSample.java
program illustrates how to validate against an implicit XML Schema. The validation mode is implicit because the XML schema is referenced in the instance document itself.
Follow the steps in this section to write programs that use the setValidationMode()
method of the oracle.xml.parser.v2.
DOMParser
class:
Create a DOM parser to use for the validation of an instance document. The following code fragment from XSDSample.java
illustrates how to create the DOMParser
object:
public class XSDSample { public static void main(String[] args) throws Exception { if (args.length != 1) { System.out.println("Usage: java XSDSample <filename>"); return; } process (args[0]); } public static void process (String xmlURI) throws Exception { DOMParser dp = new DOMParser(); URL url = createURL(xmlURI); ... } ... }
createURL()
is a helper method that constructs a URL from a filename passed to the program as an argument.
Set the validation mode for the validating DOM parser with the DOMParser.setValidationMode()
method. For example, XSDSample.java
shows how to specify XML schema validation:
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace(true);
Set the output error stream with the DOMParser.setErrorStream()
method. For example, XSDSample.java
sets the error stream for the DOM parser object as follows:
dp.setErrorStream (System.out);
Validate the instance document with the DOMParser.parse()
method. You do not have to create an XML schema object explicitly because the schema is internally referenced by the instance document. For example, XSDSample.java
validates the instance document as follows:
try { System.out.println("Parsing "+xmlURI); dp.parse(url); System.out.println("The input file <"+xmlURI+"> parsed without errors"); } catch (XMLParseException pe) { System.out.println("Parser Exception: " + pe.getMessage()); } catch (Exception e) { System.out.println("NonParserException: " + e.getMessage()); }
The $ORACLE_HOME/xdk/demo/java/schema/XSDSetSchema.java
program illustrates how to validate an XML schema explicitly. The validation mode is explicit because you use the XSDBuilder
class to specify the schema to use for validation: the schema is not specified in the instance document as in implicit validation.
Follow the basic steps in this section to write Java programs that use the build()
method of the oracle.xml.parser.schema.XSDBuilder
class:
Build an XML schema object from the XML schema document with the XSDBuilder.build()
method. The following code fragment from XSDSetSchema.java
illustrates how to create the object:
public class XSDSetSchema { public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println("Usage: java XSDSample <schema_file> <xml_file>"); return; } XSDBuilder builder = new XSDBuilder(); URL url = createURL(args[0]); // Build XML Schema Object XMLSchema schemadoc = (XMLSchema)builder.build(url); process(args[1], schemadoc); } . . .
The createURL()
method is a helper method that constructs a URL from the schema document filename specified on the command line.
Create a DOM parser to use for validation of the instance document. The following code from XSDSetSchema.java
illustrates how to pass the instance document filename and XML schema object to the process()
method:
public static void process(String xmlURI, XMLSchema schemadoc)throws Exception{ DOMParser dp = new DOMParser(); URL url = createURL (xmlURI); . . .
Specify the schema object to use for validation with the DOMParser.setXMLSchema()
method. This step is not necessary in implicit validation mode because the instance document already references the schema. For example, XSDSetSchema.java
specifies the schema as follows:
dp.setXMLSchema(schemadoc);
Set the validation mode for the DOM parser object with the DOMParser.setValidationMode()
method. For example, XSDSample.java
shows how to specify XML schema validation:
dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace(true);
Set the output error stream for the parser with the DOMParser.setErrorStream()
method. For example, XSDSetSchema.java
sets it as follows:
dp.setErrorStream (System.out);
Validate the instance document against the XML schema with the DOMParser.parse()
method. For example, XSDSetSchema.java
includes the following code:
try { System.out.println("Parsing "+xmlURI); dp.parse (url); System.out.println("The input file <"+xmlURI+"> parsed without errors"); } catch (XMLParseException pe) { System.out.println("Parser Exception: " + pe.getMessage()); } catch (Exception e) { System.out.println ("NonParserException: " + e.getMessage()); }
In LAX mode, you can validate parts of the XML content of an instance document without validating the whole document. A LAX parser indicates that the processor should perform validation for elements in the instance document that are declared in an associated XML schema. The processor does not consider the instance document invalid if it contains no elements declared in the schema.
By using LAX mode, you can define the schema only for the part of the XML that you want to validate. The $ORACLE_HOME/xdk/demo/java/schema/XSDLax.java
program illustrates how to use LAX validation. The program follows the basic steps described in "Validating Against Externally Referenced XML Schemas":
Build an XML schema object from the user-specified XML schema document.
Create a DOM parser to use for validation of the instance document.
Specify the XML schema to use for validation.
Set the validation mode for the DOM parser object.
Set the output error stream for the parser.
Validate the instance document against the XML schema by calling DOMParser.parse()
.
To enable LAX validation, the program sets the validation mode in the parser to SCHEMA_LAX_VALIDATION
rather than to SCHEMA_VALIDATION
. The following code fragment from XSDLax.java
illustrates this technique:
dp.setXMLSchema(schemadoc); dp.setValidationMode(XMLParser.SCHEMA_LAX_VALIDATION); dp.setPreserveWhitespace (true); . . .
You can test LAX validation by running the sample program as follows:
java XSDLax embeded_xsql.xsd embeded_xsql.xml
The $ORACLE_HOME/xdk/demo/java/schema/xsdsax.java
program illustrates how to validate an XML document received as a SAX stream. You instantiate an XSDValidator
and register it with the SAX parser as the content handler.
Follow the steps in this section to write programs that validate XML from a SAX stream:
Build an XML schema object from the user-specified XML schema document by invoking the XSDBuilder.build()
method. The following code fragment from illustrates how to create the object:
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(args[0]); // Build XML Schema Object XMLSchema schemadoc = (XMLSchema)builder.build(url); process(args[1], schemadoc); . . .
createURL()
is a helper method that constructs a URL from the filename specified on the command line.
Create a SAX parser (SAXParser
object) to use for validation of the instance document. The following code fragment from saxxsd.java
passes the handles to the XML document and schema document to the process()
method:
process(args[1], schemadoc);...public static void process(String xmlURI, XMLSchema schemadoc) throws Exception { SAXParser dp = new SAXParser(); ...
Configure the SAX parser. The following code fragment sets the validation mode for the SAX parser object with the XSDBuilder.setValidationMode()
method:
dp.setPreserveWhitespace (true); dp.setValidationMode(XMLParser.NONVALIDATING);
Create and configure a validator (XSDValidator
object). The following code fragment illustrates this technique:
XMLError err;... err = new XMLError(); ... XSDValidator validator = new XSDValidator(); ... validator.setError(err);
Specify the XML schema to use for validation by invoking the XSDBuilder.setXMLProperty()
method. The first argument is the name of the property, which is fixedSchema
, and the second is the reference to the XML schema object. The following code fragment illustrates this technique:
validator.setXMLProperty(XSDNode.FIXED_SCHEMA, schemadoc); ...
Register the validator as the SAX content handler for the parser. The following code fragment illustrates this technique:
dp.setContentHandler(validator); ...
Validate the instance document against the XML schema by invoking the SAXParser.parse()
method. The following code fragment illustrates this technique:
dp.parse (url);
The $ORACLE_HOME/xdk/demo/java/schema/xsddom.java
program shows how to validate an instance document by obtain a DOM representation of the document and using an XSDValidator
object to validate it.
The xsddom.java
program follows these steps:
Build an XML schema object from the user-specified XML schema document by invoking the XSDBuilder.build()
method. The following code fragment from illustrates how to create the object:
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(args[0]); XMLSchema schemadoc = (XMLSchema)builder.build(url); process(args[1], schemadoc);
createURL()
is a helper method that constructs a URL from the filename specified on the command line.
Create a DOM parser (DOMParser
object) to use for validation of the instance document. The following code fragment from domxsd.java
passes the handles to the XML document and schema document to the process()
method:
process(args[1], schemadoc);...public static void process(String xmlURI, XMLSchema schemadoc) throws Exception { DOMParser dp = new DOMParser(); . . .
Configure the DOM parser. The following code fragment sets the validation mode for the parser object with the DOMParser.setValidationMode()
method:
dp.setPreserveWhitespace (true); dp.setValidationMode(XMLParser.NONVALIDATING); dp.setErrorStream (System.out);
Parse the instance document. The following code fragment illustrates this technique:
dp.parse (url);
Obtain the DOM representation of the input document. The following code fragment illustrates this technique:
XMLDocument doc = dp.getDocument();
Create and configure a validator (XSDValidator
object). The following code fragment illustrates this technique:
XMLError err;... err = new XMLError(); ... XSDValidator validator = new XSDValidator(); ... validator.setError(err);
Specify the schema object to use for validation by invoking the XSDBuilder.setXMLProperty()
method. The first argument is the name of the property, which in this example is fixedSchema
, and the second is the reference to the schema object. The following code fragment illustrates this technique:
validator.setXMLProperty(XSDNode.FIXED_SCHEMA, schemadoc); . . .
Obtain the root element (XMLElement
) of the DOM tree and validate. The following code fragment illustrates this technique:
XMLElement root = (XMLElement)doc.getDocumentElement(); XMLElement copy = (XMLElement)root.validateContent(validator, true); copy.print(System.out);
The $ORACLE_HOME/xdk/demo/java/schema/xsdproperty.java
program shows how to configure the XML Schema processor to validate an XML document based on a complex type or element declaration.
The xsdproperty.java
program follows these steps:
Create String
objects for the instance document name, XML schema name, root node namespace, root node local name, and specification of element or complex type ("true" means the root node is an element declaration). The following code fragment illustrates this technique:
String xmlfile = args[0]; String xsdfile = args[1]; ... String ns = args[2]; //namespace for the root node String nm = args[3]; //root node's local name String el = args[4]; //true if root node is element declaration, // otherwise, the root node is a complex type
Create an XSD builder and use it to create the schema object. The following code fragment illustrates this technique:
XSDBuilder builder = new XSDBuilder(); URL url = XMLUtil.createURL(xsdfile); XMLSchema schema; ... schema = (XMLSchema) builder.build(url);
Obtain the node. Invoke different methods depending on whether the node is an element declaration or a complex type:
If the node is an element declaration, pass the local name and namespace to the getElement()
method of the schema object.
If the node is an element declaration, pass the namespace, local name, and root complex type to the getType()
method of the schema object.
xsdproperty.java
uses the following control structure:
QxName qname = new QxName(ns, nm); ... XSDNode nd; ... if (el.equals("true")) { nd = schema.getElement(ns, nm); /* process ... */ } else { nd = schema.getType(ns, nm, XSDNode.TYPE); /* process ... */ }
After obtaining the node, create a new parser and set the schema to the parser to enable schema validation. The following code fragment illustrates this technique:
DOMParser dp = new DOMParser(); URL url = XMLUtil.createURL (xmlURI);
Set properties on the parser and then parse the URL. Invoke the schemaValidatorProperty()
method as follows:
Set the root element or type property on the parser to a fully qualified name.
For a top-level element declaration, set the property name to XSDNode.ROOT_ELEMENT
and the value to a QName
, as illustrated by the process1()
method.
For a top-level type definition, set the property name to XSDNode.ROOT_TYPE
and the value to a QName
, as illustrated by the process2()
method.
Set the root node property on the parser to an element or complex type node.
For an element node, set the property name to XSDNode.ROOT_NODE
and the value to an XSDElement
node, as illustrated by the process3()
method.
For a type node, set the property name to XSDNode.ROOT_NODE
and the value to an XSDComplexType
node, as illustrated by the process3()
method.
The following code fragment shows the sequence of method invocation:
if (el.equals("true")) { nd = schema.getElement(ns, nm); process1(xmlfile, schema, qname); process3(xmlfile, schema, nd); } else { nd = schema.getType(ns, nm, XSDNode.TYPE); process2(xmlfile, schema, qname); process3(xmlfile, schema, nd); }
The processing methods are implemented as follows:
static void process1(String xmlURI, XMLSchema schema, QxName qname) throws Exception { /* create parser... */ dp.setXMLSchema(schema); dp.setSchemaValidatorProperty(XSDNode.ROOT_ELEMENT, qname); dp.setPreserveWhitespace (true); dp.setErrorStream (System.out); dp.parse (url); ... } static void process2(String xmlURI, XMLSchema schema, QxName qname) throws Exception { /* create parser... */ dp.setXMLSchema(schema); dp.setSchemaValidatorProperty(XSDNode.ROOT_TYPE, qname); dp.setPreserveWhitespace (true); dp.setErrorStream (System.out); dp.parse (url); ... } static void process3(String xmlURI, XMLSchema schema, XSDNode node) throws Exception { /* create parser... */ dp.setXMLSchema(schema); dp.setSchemaValidatorProperty(XSDNode.ROOT_NODE, node); dp.setPreserveWhitespace (true); dp.setErrorStream (System.out); dp.parse (url); ... }
The oracle.xml.schemavalidator.XSDValidator
bean encapsulates the oracle.xml.parser.schema.XSDValidator
class and adds functionality for validating a DOM tree. The parser builds the DOM tree for the instance document and XML schema document and validates the instance document against the schema.
The XSDValidatorSample.java
program in $ORACLE_HOME/xdk/demo/java/transviewer
illustrates how to use the XSDValidator
bean.
Follow the basic steps in this section to write Java programs that use the XSDValidator
bean:
Parse the instance document with the DOMParser.parse()
method. The following code fragment from XSDValidatorSample.java
illustrates this technique:
URL xmlinstanceurl, schemaurl; XMLDocument xmldoc1,xmldoc2; // get the URL for the input files xmlinstanceurl = createURL(args[0]); // Parse the XML Instance document first xmldoc1 = parseXMLDocument(xmlinstanceurl);
createURL()
is a helper method that creates a URL from a filename. The parseXMLDocument()
method receives a URL as input and parses it with the DOMParser.parse()
method as follows:
DOMParser parser = new DOMParser(); parser.parse(xmlurl); return parser.getDocument();
Parse the XML schema document with the DOMParser.parse()
method. The following code from XSDValidatorSample.java
illustrates this technique:
schemaurl = createURL(args[1]);xmldoc2 = parseXMLDocument(schemaurl);
Build the schema object from the parsed XML schema with the XSDBuilder.build()
method. The following code fragment from XSDValidatorSample.java
illustrates this technique:
XSDBuilder xsdbuild = new XSDBuilder(); . . . xmlschema = (XMLSchema)xsdbuild.build(xmldoc2, createURL(args+"builder"));
Specify the schema object to use for validation by passing a reference to the XSDValidator.setSchema()
method. The following code fragment from XSDValidatorSample.java
creates the validator and sets the schema:
XSDValidator xsdval = new XSDValidator(); . . . xsdval.setSchema(xmlschema);
Set the error output stream for the validator by invoking the XSDValidator.setError()
method. The following code fragment from XSDValidatorSample.java
illustrates how to create the object:
Properties p = new Properties(System.getProperties()); p.load(new FileInputStream("demo.properties")); System.setProperties(p); . . . XMLError err = new XMLError(); . . . err.setErrorHandler(new DocErrorHandler()); . . . xsdval.setError(err);
Validate the instance document against the schema by passing a reference to instance document to the XSDValidator.validate()
method. For example, XSDValidatorSample.java
includes the following code fragment:
xsdval.validate(xmldoc1);
This section contains the following topics:
When the XSDBuilder
builds a schema, it may need to include or import other schemas specified as URLs in the schemaLocation
attribute. The xsdent.java
demo described in Table 5-3 illustrates this case. The document element in xsdent.xml
file contains the following attribute:
xsi:schemaLocation = "http://www.somewhere.org/BookCatalogue xsdent.xsd">
The xsdent.xsd
document contains the following elements:
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.somewhere.org/BookCatalogue" xmlns:catd = "http://www.somewhere.org/Digest" xmlns:cat = "http://www.somewhere.org/BookCatalogue" elementFormDefault="qualified"> <import namespace = "http://www.somewhere.org/Digest" schemaLocation = "xsdent-1.xsd" />
In some cases, you may want to override the schema locations specified in <import>
and supply the builder with the required schema documents. For example, you may have downloaded the schemas documents from external Web sites and stored them in a database. In such cases, you can set an entity resolver in the XSDBuilder
. XSDBuilder
passes the schema location to the resolver, which returns an InputStream
, Reader
, or URL
as an InputSource. The builder can read the schema documents from the InputSource
.
The xsdent.java
program illustrates how you can override the schema location with an entity resolver. You must implement the EntityResolver
interface, instantiate the entity resolver, and set it in the XML schema builder. In the demo code, sampleEntityResolver1
returns InputSource
as an InputStream
whereas sampleEntityResolver2
returns InputSource
as a URL
.
Follow these basic steps:
Create a new XML schema builder as follows:
XSDBuilder builder = new XSDBuilder();
Set the builder to your entity resolver. An entity resolver is a class that implements the EntityResolver
interface. The purpose of the resolver is to enable the XML reader to intercept any external entities before including them. The following code fragment creates an entity resolver and sets it in the builder:
builder.setEntityResolver(new sampleEntityResolver1());
The sampleEntityResolver1
class implements the resolveEntity()
method. You can use this method to redirect external system identifiers to local URIs. The source code is as follows:
class sampleEntityResolver1 implements EntityResolver { public InputSource resolveEntity (String targetNS, String systemId) throws SAXException, IOException { // perform any validation check if needed based on targetNS & systemId InputSource mySource = null; URL u = XMLUtil.createURL(systemId); // Create input source with InputStream as input mySource = new InputSource(u.openStream()); mySource.setSystemId(systemId); return mySource; } }
Note that sampleEntityResolver1
initializes the InputSource
with a stream.
Build the XML schema object. The following code illustrates this technique:
schemadoc = builder.build(url);
Validate the instance document against the XML schema. The program executes the following statement:
process(xmlfile, schemadoc);
The process()
method creates a DOM parser, configures it, and invokes the parse()
method. The method is implemented as follows:
public static void process(String xmlURI, Object schemadoc) throws Exception { DOMParser dp = new DOMParser(); URL url = XMLUtil.createURL (xmlURI); dp.setXMLSchema(schemadoc); dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace (true); dp.setErrorStream (System.out); try { dp.parse (url); ... }
Because of the power and flexibility of the XML Schema language, you may want to convert your existing DTDs to XML Schema documents. The XDK API enables you to perform this transformation.
The $ORACLE_HOME/xdk/demo/java/schema/DTD2Schema.java
program illustrates how to convert a DTD. You can test the program as follows:
java DTD2Schema dtd2schema.dtd dtd2schema.xml
Follow these basic steps to convert a DTD to an XML schema document:
Parse the DTD with the DOMParser.parseDTD()
method. The following code fragment from DTD2Schema.java
illustrates how to create the DTD object:
XSDBuilder builder = new XSDBuilder(); URL dtdURL = createURL(args[0]); DTD dtd = getDTD(dtdURL, "abc");
The getDTD()
method is implemented as follows:
private static DTD getDTD(URL dtdURL, String rootName) throws Exception { DOMParser parser = new DOMParser(); DTD dtd; parser.setValidationMode(true); parser.setErrorStream(System.out); parser.showWarnings(true); parser.parseDTD(dtdURL, rootName); dtd = (DTD)parser.getDoctype(); return dtd; }
Convert the DTD to an XML schema DOM tree with the DTD.convertDTD2Sdhema()
method. The following code fragment from DTD2Schema.java
illustrates this technique:
XMLDocument dtddoc = dtd.convertDTD2Schema();
Write the XML schema DOM tree to an output stream with the XMLDocument.print()
method. The following code fragment from DTD2Schema.java
illustrates this technique:
FileOutputStream fos = new FileOutputStream("dtd2schema.xsd.out"); dtddoc.print(fos);
Create an XML schema object from the schema DOM tree with the XSDBuilder.build()
method. The following code fragment from DTD2Schema.java
illustrates this technique:
XMLSchema schemadoc = (XMLSchema)builder.build(dtddoc, null);
Validate an instance document against the XML schema with the DOMParser.parse()
method. The following code fragment from DTD2Schema.java
illustrates this technique:
validate(args[1], schemadoc);
The validate()
method is implemented as follows:
DOMParser dp = new DOMParser(); URL url = createURL (xmlURI); dp.setXMLSchema(schemadoc); dp.setValidationMode(XMLParser.SCHEMA_VALIDATION); dp.setPreserveWhitespace (true); dp.setErrorStream (System.out); try { System.out.println("Parsing "+xmlURI); dp.parse (url); System.out.println("The input file <"+xmlURI+"> parsed without errors"); } ...