Jak zweryfikować schemat w JAXB 2.0 bez rozpisywania?

Muszę zweryfikować moje obiekty JAXB przed przeniesieniem do pliku XML. Przed JAXB 2.0 można było używać javaxa.xml.bind.Walidator. Ale to było przestarzałe, więc staram się znaleźć właściwy sposób na to. Znam walidację w czasie Marshalla, ale w moim przypadku chcę tylko wiedzieć, czy jest ważna. Przypuszczam, że mógłbym wrzucić plik tymczasowy lub pamięć i wyrzucić go, ale zastanawiam się, czy nie ma bardziej eleganckiego rozwiązania.

 46
Author: skaffman, 2009-10-13

3 answers

Po Pierwsze, javax.xml.bind.Validator został zdeprecjonowany na rzecz javax.xml.validation.Schema (javadoc ). Chodzi o to, że analizujesz swój schemat za pomocą javax.xml.validation.SchemaFactory (javadoc ) i wstrzyknąć to do marshaller/unmarshaller.

Jeśli chodzi o twoje pytanie dotyczące walidacji bez marszowania, problem polega na tym, że JAXB faktycznie deleguje walidację do Xerces (lub dowolnego procesora SAX, którego używasz), a Xerces sprawdza twój dokument jako strumień zdarzeń SAX. Więc aby potwierdzić, musisz wykonaj jakiś rodzaj

Implementacja o najmniejszym wpływie to użycie implementacji"/dev / null " procesora SAX. Przekierowanie do strumienia wyjściowego null nadal wiązałoby się z generowaniem XML, co jest marnotrawstwem. Więc proponuję:

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 odrzuci wszystkie zdarzenia, a operacja marshal() spowoduje odrzucenie JAXBException, jeśli Walidacja względem schematu nie powiedzie się.

 71
Author: skaffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-08 09:37:07

Możesz użyć javax.xml.bind.util.JAXBSource (javadoc ) oraz javax.xml.validation.Validator (javadoc ), dorzucić implementację org.xml.sax.ErrorHandler (javadoc) i wykonaj następujące czynności:

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);
    }

}

Więcej Informacji Można Znaleźć Na Moim Blogu

 11
Author: Blaise Doughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-08 10:57:21

Tak to zrobiliśmy. Musiałem znaleźć sposób na walidację pliku xml w porównaniu z XSD odpowiadającym wersji xml, ponieważ mamy wiele aplikacji korzystających z różnych wersji zawartości xml.

Naprawdę nie znalazłem żadnych dobrych przykładów w sieci i w końcu skończyłem z tym. Mam nadzieję, że to pomoże.

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
Author: Pat B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-09 03:38:22