How to check schema in JAXB 2.0 without sorting?

I need to check my JAXB objects before sorting into an XML file. Prior to JAXB 2.0, you could use javax.xml.bind.Validator. But this is out of date, so I'm trying to figure out how to do it. I am familiar with checking for marshall time, but in my case I just want to know if this is true. I suppose I could go to a temporary file or memory and throw it away, but I wonder if there is a more elegant solution.

+45
java jaxb
Oct 13 '09 at 13:57
source share
3 answers

Firstly, javax.xml.bind.Validator deprecated in favor of javax.xml.validation.Schema ( javadoc ). The idea is that you parse your schema using javax.xml.validation.SchemaFactory ( javadoc ) and enter this into the marshaller / unmarshaller.

As for your question regarding validation without sorting, the problem here is that JAXB actually delegates the check to Xerces (or whatever SAX processor you use), and Xerces checks your document as a SAX event stream. Therefore, to check, you need to do some sort of sorting.

The least efficient implementation of this will be to use the "/ dev / null" implementation of the SAX processor. Marshalling on a null OutputStream will still involve creating XML, which is wasteful. Therefore, 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 events, and the marshal() operation will throw a JAXBException if the validation check for the schema fails.

+67
Oct. 14 '09 at 7:36
source share

You can use javax.xml.bind.util.JAXBSource ( javadoc ) and javax.xml.validation.Validator ( javadoc ), enter the 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.

+10
Nov 13 '12 at 12:28
source share

How we did it. I had to find a way to check the xml file against the xsd corresponding to the xml version, since we have many applications using different versions of xml content.

I really did not find any good examples on the net and finally ended up with this. Hope this helps.

 ValidationEventCollector vec = new ValidationEventCollector(); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); URL xsdURL = getClass().getResource("/xsd/" + xsd); Schema schema = sf.newSchema(xsdURL); //You should change your jaxbContext here for your stuff.... Unmarshaller um = (getJAXBContext(NotificationReponseEnum.NOTIFICATION, notificationWrapper.getEnteteNotification().getTypeNotification())) .createUnmarshaller(); um.setSchema(schema); try { StringReader reader = new StringReader(xml); um.setEventHandler(vec); um.unmarshal(reader); } catch (javax.xml.bind.UnmarshalException ex) { if (vec != null && vec.hasEvents()) { erreurs = new ArrayList < MessageErreur > (); for (ValidationEvent ve: vec.getEvents()) { MessageErreur erreur = new MessageErreur(); String msg = ve.getMessage(); ValidationEventLocator vel = ve.getLocator(); int numLigne = vel.getLineNumber(); int numColonne = vel.getColumnNumber(); erreur.setMessage(msg); msgErreur.setCode(ve.getSeverity()) erreur.setException(ve.getLinkedException()); erreur.setPosition(numLigne, numColonne); erreurs.add(erreur); logger.debug("Erreur de validation xml" + "erreur : " + numLigne + "." + numColonne + ": " + msg); } } } 
+4
Sep 27 '11 at 21:10
source share



All Articles