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.
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:
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.XmlOptions.setCompileNoValidation
method.)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: The exception to this rule is that XMLBeans validates your schema when you're compiling it using scomp or the xmlbean Ant task.
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:
XMLBeans tools for validation include command-line tools and APIs.
Among the many command-line tools XMLBeans provides, you'll find two that are specifically for validation.
You'll find the validate
tool in the bin directory of your XMLBeans installation.
You'll find the svalidate
tool in the bin directory of your XMLBeans installation.
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.
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:
Also, see the section on validating as you go for information about using the XmlOptions.setValidateOnSet
method.
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"); } }
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: 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 ...