2012-11-16 4 views
17

L'esecuzione del comando seguente xjc genera un errore:XJC: Due dichiarazioni provocano una collisione nella classe ObjectFactory

$ 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 

Anche se capisco le associazioni JAXB e ciò che siamo è il conflitto in XJC, non lo faccio capire dove si trova il conflitto nello schema corrente.

come devo risolvere questo?

Grazie,

Pierre

aggiornamento: qui è il contesto degli errori:

$ 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 
+0

Non credo che nessuno possa aiutarti se non fornisci parti rilevanti da Core.xsd – hoaz

risposta

24

citerò dal the most official unofficial guide on JAXB in rete.

Quando gli schemi contengono simili nomi elemento Looking/tipo, possono risultato in "Due dichiarazioni causare una collisione nei ObjectFactory classe" errori. Per essere più precisi, per tutti i tipi e molti elementi (esattamente quali elementi ottengono una fabbrica e cosa no è il bit difficile da spiegare), XJC produce un metodo nella classe ObjectFactory nello stesso pacchetto. La classe ObjectFactory viene creata per ciascun pacchetto in cui XJC genera alcuni file. Il nome del metodo è derivato da nomi di elementi/tipi XML e l'errore viene segnalato se due elementi/tipi provano a generare lo stesso nome di metodo.

Detto questo, hai due opzioni.

Il primo è quello di definire un XML esterno vincolante come questo

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

Nella generato ObjectFactory classe di questo creerà due metodi chiamati createTypeBioSampleSet e createTypeTargetBioSampleSet (JAXB aggiungerà il nome specificato per la parola create) che può essere utilizzato per produrre oggetti BioSampleSet e TargetBioSampleSet.

(non è necessario definire un vincolante per entrambi i tipi.)

Io non sono esattamente sicuro perché JAXB rifiuta di generare classi dalla data dello schema, ma quando ho specificato un solo vincolante (per BioSampleSet per esempio) quindi il metodo factory dell'altro tipo è stato chiamato come createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse, quindi penso che JAXB si sia soffermato su questo identificatore di metodo lungo, perché in qualche modo è riuscito a creare lo stesso per entrambi i tipi. Penso che questo sia un dettaglio di implementazione in JAXB.

L'altra soluzione è quella di creare un tipo di base per un BioSampleSet e l'uso che in entrambi i luoghi come questo

<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 soluzione migliore sarebbe quella di abbandonare ogni dichiarazioni di tipo anonime dal vostro schema. Se puoi farlo, fallo, perché questo schema sembra un casino (almeno per me).

+0

"Non sono esattamente sicuro del motivo per cui JAXB si rifiuta di generare classi dallo schema dato": neanche io, ma grazie mille, ha funzionato! :-) – Pierre

+0

@ Kohányi Róbert Bella risposta, ha risolto il mio problema. Molte grazie! – user1516873

+0

Grazie per il suggerimento, mi stavo chiedendo perché non riesco a trovare alcun elemento factoryMethod nello schema http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/jaxb/bindingschema_2_0.xsd, sebbene sia documentato in https://jaxb.java.net/nonav/2.0/binding-customization/http.java.sun.com.xml.n/index.html – kasi