The Apache Software Foundation > Apache XMLBeans
 

Validation with XMLBeans

Validation with XMLBeans

An essential part of schema-related work is validating instances based on the schema. XMLBeans provides a number of ways for you to ensure your instances are valid, both at the command line and programmatically at run time.

Validation, XMLBeans-Style

XMLBeans' schema-oriented approach to handling XML makes validation an important part of its work. However, XMLBeans has a specific approach to validation that's helpful to keep in mind when you're working.

Validation features include the following:

  • Generally, XMLBeans validates when you ask it to. It doesn't validate while parsing -- nor, by default, while your code is updating the bound instance along the way through, say, set* methods (although you can change this behavior).
  • You can validate programmatically or by using one of the command-line tools provided by XMLBeans.
  • The validate methods return true or false to indicate whether the instance is valid. You can also capture error information if you want to when validating programmatically. To do this, you specify an error listener.
  • You can tell XMLBeans at parse time that it should validate during calls to set* methods. Note that this means validation after parsing, not during, and that it can slow performance. Also note validation would not occur as changes are made by a cursor.
  • XMLBeans does validate schema when compiling the schema through scomp or the xmlbean Ant task. (When you're compiling schema programmatically, you can disable validation with the XmlOptions.setCompileNoValidation method.)

>XMLBeans Validates Only When You Ask It To — Generally

Given XMLBeans' focus on schema-oriented work, it's natural to assume that it might check up on you as your code is making changes to an instance — that it might prevent your code from doing something that would render the instance invalid along the way. But, by default, it doesn't. The design of XMLBeans assumes that an XML instance might go through multiple invalid states before changes are complete. As a result, generally speaking, XMLBeans keeps quiet while changes are occurring.

Note
Note: The exception to this rule is that XMLBeans validates your schema when you're compiling it using scomp or the xmlbean Ant task.

XMLBeans Does Not Validate an Instance While Parsing It

But it's not hard to get the impression that it does. For example, imagine that you're parsing an XML instance using a statement such as the following:

MyXmlSchemaType myXmlBean = MyXmlSchemaType.Factory.parse(myXml);

If the namespace declared in the myXml instance doesn't match the target namespace of the schema from which MyXmlSchemaType was generated, parsing will fail with an error message. Likewise, you'll get messages for other mismatches between the shape of myXml and the XML shape described by the schema.

But these failures and messages don't result from validation. Instead, all XMLBeans is doing is a not-very-deep check to see if the instance shouldn't be bound to the XMLBeans type generated from schema. In other words, the checking done at the parsing stage is simply a "low bar" effort to avoid trouble down the road.

Validation, on the other hand, is designed to verify that the instance conforms completely to the schema.

So you can validate in any of three ways:

  • On request, using a validate method.
  • On the fly, using the "validate on set" option.
  • Using one of the command-line tools.

Tools for Validating

XMLBeans tools for validation include command-line tools and APIs.

Command-line Tools for Validation

Among the many command-line tools XMLBeans provides, you'll find two that are specifically for validation.

  • validate tool — A validation command-line tool in which you specify the instance to validate and the schema to validate it against.

    You'll find the validate tool in the bin directory of your XMLBeans installation.

  • svalidate tool — Identical to the validate tool, except that svalidate uses a streaming model that supports validation against much larger schemas.

    You'll find the svalidate tool in the bin directory of your XMLBeans installation.

APIs for Validation

XMLBeans APIs provide ways for you to validate on request —say, after your code has finished editing an instance and before it passes the instance elsewhere. You can also specify that your calls to set* methods should validate on-the-fly the instance that is being edited; you do this as an option when your code creates the XMLBeans schema type instance.

Validation When You Ask for It

Both the validate methods described here are available from any XMLBeans type generated from schema during schema compilation (because all such types inherit from XmlObject). Both methods are designed to validate the instance that is bound to the type from which the method is called. For example, if your schema defines a <purchase-order> element with <item> children, calling the myItem.validate() method will validate the <item> instance bound to Item. This includes the <item> element's children, but not the <purchase-order> element or the <item> element's siblings.

Both methods return a boolean to indicate validity, and one of the methods lets you specify options for validation, such as capturing messages about why an invalid instance is invalid.

  • XmlObject.validate() — Returns true if the instance is valid.
  • XmlObject.validate(XmlOptions) — Returns true if the instance is valid, using the specified XmlOptions instance to customize validation.

    In particular, you can use the XmlOptions.setErrorListener method to specify a Collection instance with which to capture messages pertaining to invalid instances. For an example, see the Javadoc for this method.

    Through the XmlOptions class, you can specify options to use during validation. The options include the following:

  • XmlOptions.setErrorListener -- Specifies a Collection instance that XMLBeans should use to store errors that occur during validation (or, in other contexts, during parsing and compilation).
  • XmlOptions.setValidateTreatLaxAsSkip -- Tells XMLBeans that it should skip elements matching an particle with contentModel="lax" during validation.

Also, see the section on validating as you go for information about using the XmlOptions.setValidateOnSet method.

Retrieving Error Messages About Invalid XML

When you'll be validating with one of the validate methods, you can specify a java.util.Collection implementation as an error listener. As validation occurs, errors are added to the listener. After validation (and if the instance is found to be invalid) you can examine the errors. Here's an example:

// Set up the validation error listener.
ArrayList validationErrors = new ArrayList();
XmlOptions validationOptions = new XmlOptions();
validationOptions.setErrorListener(validationErrors);
MyDocument myDoc = MyDocument.Factory.parse(pathToXml);
// Do some editing to myDoc.
// During validation, errors are added to the ArrayList for
// retrieval and printing by the printErrors method.
boolean isValid = myDoc.validate(validationOptions);
// Print the errors if the XML is invalid.
if (!isValid) {
Iterator iter = validationErrors.iterator();
while (iter.hasNext()) {
System.out.println(">> " + iter.next() + "\n");
}
}

Validation As You Go

By default, an XML instance will not be validated at run time as your code makes changes. However, you can change this behavior for limited on-the-fly validation. To do this, you specify the "validate on set" option when you create the XMLBeans type instance — you do this with the XmlOptions.setValidateOnSet method.

When you specify this option, XMLBeans with throw an exception when your code invalidates the XML through a set* method. Note that you can't specify an error listener for use in conjunction with this means of validating. Also, with "validate on set," only simple schema types will be validated. Schema types not validated by this approach include, for example, those defining elements with attributes or elements with children.

Because its functionality is limited to simple schema types and it validates for set* method calls, you should regard this validation approach as a debugging tool, rather than an alternative to using a validate method. For example, you might use it to determine which errant bit of code is creating an invalid chunk of XML.

Note
Note: This sort of validation is not supported during changes you make using an XmlCursor instance.

Among the methods you can use to create an XMLBeans instance — the parse methods and the newInstance method — you'll find versions that take an XmlOptions instance as a parameter. Specifying this option would look something like the following:

XmlOptions validateOptions = new XmlOptions();
// Tell XMLBeans you want to validate on the fly.
validateOptions.setValidateOnSet();
// Create the new instance, specifying the option.
PurchaseOrder newPo = PurchaseOrder.Factory.newInstance(validateOptions);
// ... Code to edit the instance via get and set methods ...

Related Topics