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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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