Problème de validation XML avec JAXB
Bonjour à tous,
J'ai un petit souci de validation XML.
J'explique rapidement le contexte : Dans le cadre d'un projet Java, j'utilise un fichier XML pour définir une structure de données transformées en objets Java en utilisant JAXB. Ce XML est d'abord soumis à vérification de validité.
Voici le code Java :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public void test() throws Exception {
URL structXMLFile = this.getClass().getResource("structure.xml");
ObjectFactory beanJaxbFactory = new ObjectFactory();
TypeHierarchy typeHierarchy = beanJaxbFactory.createTypeHierarchy();
typeHierarchy = (TypeHierarchy) this.load(structXMLFile, "/com/altair/generic/util/ModeleStructure.xsd", typeHierarchy);
}
private Object load(URL xmlFile, String XSDModel, Object beanJAXB) throws JAXBException, SAXException, ClassNotFoundException, FileLoaderException {
CustomValidationEventHandler handler = new CustomValidationEventHandler();
JAXBContext jc = JAXBContext.newInstance(beanJAXB.getClass().getPackage().getName());
Unmarshaller unmarshaller = jc.createUnmarshaller();
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(this.getClass().getResource(XSDModel));
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(handler);
Object o = unmarshaller.unmarshal(xmlFile);
if (handler.getEvents().size() > 0) {
for (ValidationEvent e : handler.getEvents()) {
System.out.println(e.getMessage());
}
throw new FileLoaderException(MessageFormat.format(FileLoaderManager.FILE_LOADER_VALID_XML, xmlFile.getPath()));
}
return o;
} |
Et voici un extrait de mon schéma (sans les simpleTypes) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="typeHierarchy">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="groupe"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="groupe">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="type"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="reference"/>
</xs:sequence>
<xs:attribute name="id" type="libelle" use="required"/>
<xs:attribute name="multiplicite" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="type">
<xs:complexType>
<xs:attribute name="typeLigne" type="typeLigne" use="required"/>
<xs:attribute name="codeNature" type="codNature" use="optional"/>
<xs:attribute name="obligatoire" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="reference">
<xs:complexType>
<xs:attribute name="groupe" type="libelle" use="required"/>
<xs:attribute name="obligatoire" type="xs:boolean" use="required"/>
</xs:complexType>
</xs:element>
[...]
</xs:schema> |
L'objectif est, vous l'aurez compris, d'autoriser un XML du type :
- Une balise <typeHierarchy>
- n balises <groupe> dans <typeHierarchy>
- 0 ou 1 balise <type> en premier dans <groupe>
- 0 à n balises <reference> en second dans <groupe>
Exemple XML :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<typeHierarchy>
<groupe id="global" multiplicite="false">
<reference groupe="EnteteFichier" obligatoire="true" />
<reference groupe="ET" obligatoire="false" />
<reference groupe="EnqueueFichier" obligatoire="true" />
</groupe>
<groupe id="EnteteFichier" multiplicite="false">
<type typeLigne="01" obligatoire="true"/>
</groupe>
<groupe id="ET" multiplicite="true">
<type typeLigne="05" obligatoire="true" codeNature="010" />
<reference groupe="Personne" obligatoire="true" />
<reference groupe="Operation" obligatoire="true" />
</groupe>
<groupe id="EnqueueFichier" multiplicite="false">
<type typeLigne="09" obligatoire="true" />
</groupe>
<groupe id="Personne" multiplicite="true">
<type typeLigne="05" obligatoire="true" codeNature="020" />
<reference groupe="Evenement" obligatoire="true" />
<reference groupe="Associe" obligatoire="true" />
</groupe>
<groupe id="Evenement" multiplicite="true">
<type typeLigne="05" codeNature="030" obligatoire="false" />
</groupe>
<groupe id="Associe" multiplicite="true">
<type typeLigne="05" obligatoire="false" codeNature="040" />
</groupe>
<groupe id="Operation" multiplicite="true">
<type typeLigne="05" obligatoire="true" codeNature="050" />
<reference groupe="Contrat" obligatoire="true" />
</groupe>
<groupe id="Contrat" multiplicite="true">
<type typeLigne="05" obligatoire="true" codeNature="060" />
<reference groupe="Fraction" obligatoire="true" />
</groupe>
<groupe id="Fraction" multiplicite="true">
<type typeLigne="05" obligatoire="false" codeNature="070" />
<reference groupe="Garantie" obligatoire="true" />
</groupe>
<groupe id="Garantie" multiplicite="true">
<type typeLigne="05" obligatoire="false" codeNature="080" />
</groupe>
</typeHierarchy> |
Mon problème :
Avec mon éditeur (XMLSpear), le XML ci-dessus passe sans erreur à la validation XSD, mais lorsque je teste la validité dans le code Java (handler.getEvents() qui résulte du unmarshall()), j'ai plein d'erreurs dont le message ne me dit absolument rien : "unexpected element (uri:"", local:"reference"). Expected elements are <{}type>".
Comment est-ce possible d'avoir des écarts de validation entre un éditeur XML et ma librairie JAXB qui utilisent toutes les deux le même XSD? Quelqu'un a t-il eu le même problème? Y a t-il des erreurs dans mon XSD que mon éditeur n'a pas détécté?
Merci d'avance pour votre aide :)