Je dois valider mes objets JAXB avant de les transférer dans un fichier XML. Avant JAXB 2.0, on pouvait utiliser un fichier javax.xml.bind.Validator. Mais cela a été déconseillé et j'essaie de trouver la bonne façon de procéder. Je suis habitué à valider au marshall mais dans mon cas, je veux juste savoir si sa validité. Je suppose que je pourrais rassembler un fichier temporaire ou une mémoire et le jeter tout en me demandant s'il existe une solution plus élégante.
Réponses
Trop de publicités?Tout d'abord, javax.xml.bind.Validator
a été dépréciée en faveur de l' javax.xml.validation.Schema
. L'idée est que vous analysez votre schéma, et de les injecter dans le marshaller/unmarshaller.
Quant à votre question concernant la validation sans triage, le problème ici est que JAXB réalité des délégués de la validation de Xerces (ou n'importe quel SAX processeur que vous utilisez), et Xerces valide votre document sous forme d'un flux d'événements SAX. Donc pour valider, vous devez effectuer certains type de regroupement.
Le plus faible impact de la mise en œuvre de ce qui serait d'utiliser un "/dev/null" la mise en œuvre d'un SAX processeur. Le regroupement pour un null OutputStream nécessiterait quand même génération XML, ce qui est un gaspillage. Donc, je vous suggère:
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
supprimera tous les événements, et l' marshal()
opération de jeter un JAXBException si la validation par rapport au schéma d'échec.
Vous pouvez utiliser un javax.xml.bind.util.JAXBSource
et un javax.xml.validation.Validator
et procédez comme suit:
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);
}
}
Pour plus d'informations, voir mon blog
C'est comme ça qu'on l'a fait. Je devais trouver un moyen de valider le fichier XML par rapport à un xsd correspondant à la version du XML, car de nombreuses applications utilisent différentes versions du contenu XML.
Je n'ai pas vraiment trouvé de bons exemples sur le net et j'ai finalement fini avec ça. J'espère que cela aidera.
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);
}
}
}