web-dev-qa-db-fra.com

xjc: deux déclarations provoquent une collision dans la classe ObjectFactory

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
19
Pierre

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).

26
Kohányi Róbert