L'exécution de la commande xjc suivante génère une erreur:
$ xjc "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd"
parsing a schema...
compiling a schema...
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 340 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd
[ERROR] (Related to above error) This is the other declaration.
line 475 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd
Bien que je comprenne les liaisons JAXB et quels sont les conflits dans XJC, je ne comprends pas où se trouve le conflit dans le schéma actuel.
comment dois-je résoudre ce problème?
Merci,
Pierre
mise à jour: voici le contexte des erreurs:
$ curl -s "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd" | sed 's/^[ \t]*//' | cat -n | egrep -w -A 10 -B 10 '(340|475)'
330 <xs:element maxOccurs="1" name="Description"
331 type="xs:string" minOccurs="0">
332 <xs:annotation>
333 <xs:documentation>
334 Optionally provide description especially when "eOther" is selected
335 </xs:documentation>
336 </xs:annotation>
337 </xs:element>
338 <xs:element name="BioSampleSet" minOccurs="0" maxOccurs="1"><xs:annotation><xs:documentation>Identifier of the BioSample when known</xs:documentation>
339 </xs:annotation>
340 <xs:complexType><xs:sequence><xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
341 </xs:sequence>
342 </xs:complexType>
343 </xs:element>
344 </xs:sequence>
345 <xs:attribute name="sample_scope" use="required">
346 <xs:annotation>
347 <xs:documentation>
348 The scope and purity of the biological sample used for the study
349 </xs:documentation>
350 </xs:annotation>
--
465 <xs:documentation>Please, fill Description element when choose "eOther"</xs:documentation>
466 </xs:annotation>
467 </xs:enumeration>
468 </xs:restriction>
469 </xs:simpleType>
470 </xs:attribute>
471 </xs:complexType>
472 </xs:element>
473 <xs:element name="TargetBioSampleSet">
474 <xs:annotation><xs:documentation>Set of Targets references to BioSamples</xs:documentation></xs:annotation>
475 <xs:complexType>
476 <xs:sequence>
477 <xs:element name="ID" type="xs:token" minOccurs="1" maxOccurs="unbounded"></xs:element>
478 </xs:sequence>
479 </xs:complexType>
480 </xs:element>
481 </xs:choice>
482 <xs:element name="Method" minOccurs="1">
483 <xs:annotation>
484 <xs:documentation>
485 The core experimental approach used to obtain the data that is submitted to archival databases
Je vais citer le guide non officiel le plus officiel sur JAXB sur le net.
Lorsque les schémas contiennent des noms d'éléments/types similaires, ils peuvent entraîner des erreurs "Deux déclarations provoquent une collision dans la classe ObjectFactory". Pour être plus précis, pour chacun de tous les types et de nombreux éléments (exactement quels éléments obtiennent une fabrique et ce qui n'est pas difficile à expliquer), XJC produit une méthode sur la classe ObjectFactory dans le même package. La classe ObjectFactory est créée pour chaque package dans lequel XJC génère des fichiers. Le nom de la méthode est dérivé des noms d'élément/type XML et l'erreur est signalée si deux éléments/types tentent de générer le même nom de méthode.
Cela dit, vous avez deux options.
La première consiste à définir un XML de liaison externe comme celui-ci
<jaxb:bindings xmlns:jaxb="http://Java.Sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<jaxb:bindings schemaLocation="Core.xsd">
<jaxb:bindings node="//xs:element[@name='BioSampleSet']/xs:complexType">
<jaxb:factoryMethod name="TypeBioSampleSet"/>
</jaxb:bindings>
<jaxb:bindings node="//xs:element[@name='TargetBioSampleSet']/xs:complexType">
<jaxb:factoryMethod name="TypeTargetBioSampleSet"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
Dans la classe ObjectFactory
générée, cela créera deux méthodes appelées createTypeBioSampleSet
et createTypeTargetBioSampleSet
(JAXB ajoutera le nom que vous spécifiez au mot create
) qui peut être utilisé pour produire des objets BioSampleSet
et TargetBioSampleSet
.
(Il n'est pas nécessaire de définir une liaison pour les deux types .)
Je ne sais pas exactement pourquoi JAXB refuse de générer des classes à partir du schéma donné, mais lorsque j'ai spécifié une seule liaison (pour BioSampleSet
par exemple), la méthode d'usine de l'autre type a été nommée comme createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse
Je pense donc que JAXB s'est étouffé avec cet identifiant de méthode longue, car il a réussi à créer le même pour les deux types. Je pense que c'est un détail d'implémentation dans JAXB.
L'autre solution consiste à créer un type de base pour un BioSampleSet
et à l'utiliser à ces deux emplacements comme celui-ci
<xs:element name="ProjectTypeSubmission">
...
<xs:element name="Target">
...
<xs:element name="BioSampleSet" type="typeBioSampleSet" minOccurs="0" maxOccurs="1"/>
...
</xs:element>
...
<xs:element name="TargetBioSampleSet" type="typeBioSampleSet"/>
...
<xs:element/>
...
<xs:complexType name="typeBioSampleSet">
<xs:sequence>
<xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
</xs:sequence>
</xs:complexType>
La meilleure solution serait de supprimer toutes les déclarations de type anonyme de votre schéma. Si vous pouvez le faire, faites-le, car ce schéma ressemble à un gâchis (du moins pour moi).