Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate against schema in JAXB 2.0 without marshalling?

Tags:

java

jaxb

I need to validate my JAXB objects before marshalling to an XML file. Prior to JAXB 2.0, one could use a javax.xml.bind.Validator. But that has been deprecated so I'm trying to figure out the proper way of doing this. I'm familiar with validating at marshall time but in my case I just want to know if its valid. I suppose I could marshall to a temp file or memory and throw it away but wondering if there is a more elegant solution.

like image 546
Joel Avatar asked Oct 13 '09 13:10

Joel


People also ask

How do I validate a schema file?

If you have a WSDL file that contains an XML Schema, and you want to use this schema to validate the message, you can import the WSDL file into the Web Services Repository. The WSDL Import Wizard includes an option to automatically create a Schema Validation filter and incorporate it into the auto-generated policy.

How do I disable schema validation in JAXB?

To turn off the schema validation you should set the schema-validation-enabled property to false .


2 Answers

Firstly, javax.xml.bind.Validator has been deprecated in favour of javax.xml.validation.Schema (javadoc). The idea is that you parse your schema via a javax.xml.validation.SchemaFactory (javadoc), and inject that into the marshaller/unmarshaller.

As for your question regarding validation without marshalling, the problem here is that JAXB actually delegates the validation to Xerces (or whichever SAX processor you're using), and Xerces validates your document as a stream of SAX events. So in order to validate, you need to perform some kind of marshalling.

The lowest-impact implementation of this would be to use a "/dev/null" implementation of a SAX processor. Marshalling to a null OutputStream would still involve XML generation, which is wasteful. So I would suggest:

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(locationOfMySchema);   Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setSchema(schema); marshaller.marshal(objectToMarshal, new DefaultHandler()); 

DefaultHandler will discard all the events, and the marshal() operation will throw a JAXBException if validation against the schema fails.

like image 136
skaffman Avatar answered Sep 24 '22 01:09

skaffman


You could use a javax.xml.bind.util.JAXBSource (javadoc) and a javax.xml.validation.Validator (javadoc), throw in an implementation of org.xml.sax.ErrorHandler (javadoc) and do the following:

import java.io.File;  import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.util.JAXBSource; import javax.xml.validation.*;  public class Demo {      public static void main(String[] args) throws Exception {         Customer customer = new Customer();         customer.setName("Jane Doe");         customer.getPhoneNumbers().add(new PhoneNumber());         customer.getPhoneNumbers().add(new PhoneNumber());         customer.getPhoneNumbers().add(new PhoneNumber());          JAXBContext jc = JAXBContext.newInstance(Customer.class);         JAXBSource source = new JAXBSource(jc, customer);          SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);          Schema schema = sf.newSchema(new File("customer.xsd"));           Validator validator = schema.newValidator();         validator.setErrorHandler(new MyErrorHandler());         validator.validate(source);     }  } 

For More Information, See My Blog

  • http://blog.bdoughan.com/2010/11/validate-jaxb-object-model-with-xml.html
like image 26
bdoughan Avatar answered Sep 22 '22 01:09

bdoughan