Java中使用Schema验证

by Neeraj Bajaj

The Java API for XML Processing (JAXP) 1.3 was initially introduced in Java 2 Platform, Standard Edition (J2SE) 5.0 and is also now available in the Java Web Services Developer Pack (Java WSDP). JAXP 1.3 adds a new Schema Validation Framework (SVF), also called the Validation API, which offers advanced capabilities to efficiently validate XML against a schema. SVF also provides for much faster performance as compared to the schema validation approach in JAXP 1.2.

Before examining SVF, let's look at the earlier schema validation approach. Here's a code snippet that demonstrates that approach for SAX parsing:

   SAXParserFactory sf = SAXParserFactory.newInstance();
   sf.setNamespaceAware(true); 
   sf.setValidating(true);            
   SAXParser sp = sf.newSAXParser();
   sp.setProperty(
     SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI);
   sp.setProperty(SCHEMA_SOURCE, schema);
   sp.parse(new File(xml), dh);

The basic steps are:

  1. Create a SAXParserFactory object.
  2. Configure the SAXParserFactory object to produce parsers that support XML namespaces, and that validate documents as they are parsed.
  3. Create a SAX parser.
  4. Set SAX parser properties for the schema language and the schema source. In this example, the schema is the W3C XML Schema.
  5. Parse the document.

 

Notice that this process couples validation and XML processing.

By comparison, in the SVF approach, XML document validation against a schema is decoupled from XML processing. The first step in the SVP approach is to compile the schema:

   final String sl = XMLConstants.W3C_XML_SCHEMA_NS_URI;
   SchemaFactory factory = SchemaFactory.newInstance(sl);
   StreamSource ss = new StreamSource("mySchema.xsd");
   Schema schema = factory.newSchema(ss);

SchemaFactory is a schema compiler. It reads the given schema, checks the schema syntax and semantics according to the constraints imposed by the specified schema language, and returns a Schema object that is an immutable memory representation of the schema. Immutable here means that the set of constraints are not changed once the Schema object is created. An application that validates the same document twice against the same Schema object, must always produce the same result.

Next, you validate an XML document against the schema. There are three approaches to choose from depending upon your requirements:

  • Set the Schema instance on a DocumentBuilderFactory or SAXParserFactory
  • Create a Validator
  • Create a ValidatorHandler (to validate a SAX stream)

 

All three approaches guarantee that the XML document is validated only against the schema from which the Schema instance was obtained.

Lets look at the first approach, setting the Schema instance on a factory:

   SAXParserFactory spf = SAXParserFactory.newInstance();
   spf.setSchema(schema);
   SAXParser parser = spf.newSAXParser();
   parser.parse(<XML DOCUMENT>);

Here, the same Schema instance is passed to all the SAXParser instances created from this SAXParserFactory. The SAXParser object parses the XML document and simultaneously validates itagainst the Schema instance. Because the SAXParser does not repeatedly load the schema for every XML document that needs to be validated, this approach considerably improves the performance of the overall schema validation process. Compare this to the previous approach, where the specified schema is repeatedly loaded for every XML document that needs to be validated.

After you load a Schema object into memory, you can take the second approach, that is, use a Validator to validate an XML document against that Schema object. First you create a Validator object from the Schema object. Then you call the validate() method in the Validator object to do the validation:

   Validator v = schema.newValidator();
   v.validate(new StreamSource(xml));

The Validator object accepts java.xml.transform.Source as input. This means that it can accept either an event-based, SAX source (SAXSource) or an object-based, Document Object Model (DOM) source (DOMSource). By accepting DOMSource as input, the Validator is capable of validating an in-memory DOM Document or node against the given Schema object.

   Validator v = schema.newValidator();
   v.validate(new DOMSource(<DOM NODE>));

You might consider the Validator approach if your requirement is to validate a DOM node, or you are given a SAXSource. This approach works even if the implementation of the SAX driver is from a different vendor.

The third approach is to create a specially-designed javax.xml.validation.ValidatorHandler to validate SAX events:

   SAXParserFactory spf = SAXParserFactory.newInstance();
   spf.setNamespaceAware(true);
   XMLReader reader = spf.newSAXParser().getXMLReader();
   ValidatorHandler vh =  schema.newValidatorHandler();
   //key is to set "ValidatorHandler" as ContentHandler 
   //so that SAX event can be validated
   reader.setContentHandler(vh);
   reader.parse(xml);  

Notice that to validate the SAX events, you need to set the ValidatorHandler as the ContentHandler.

Using a ValidatorHandler, you can also validate a JDOM document against the schema. In fact, any object model (such as XOM and DOM4J) which can be built on top of a SAX stream or can produce SAX events can be used with the SVF to validate an XML document against a schema. This is possible because the ValidationHandler can validate a SAX stream. Here is a code snippet that illustrates how a JDOM document can be validated against a schema, it assumes that you obtained a ValidatorHandler as shown in the previous example:

   SAXOutputter so = new SAXOutputter(vh);
   so.output(jdomDocument);

The SAXOutputter object fires SAX events for the JDOM document. The SAX events are then validated by the ValidatorHandler.

There are other things you can do using the SVF, such as validate XML after transformation or obtain schema type information. For more information about using the SVF see the article Easy and Efficient XML Processing: Upgrade to JAXP 1.3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值