Подтвердить что ты не робот

Xjc: два объявления вызывают столкновение в классе ObjectFactory

Выполнение следующей команды xjc вызывает ошибку:

$ 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

Хотя я понимаю привязки JAXB и что такое конфликт в XJC, я не понимаю, где конфликт в текущей схеме.

Как мне это исправить?

Спасибо,

Пьер

update: вот контекст ошибок:

$ 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
4b9b3361

Ответ 1

Я приведу из самое официальное неофициальное руководство по JAXB в сети.

Если схемы содержат похожие типы элементов/типов, они могут результат: "Два объявления вызывают столкновение в ObjectFactory класс". Точнее, для каждого из всех типов и многих элементы (точно, какие элементы получают factory, а что не бит сложно объяснить), XJC производит один метод в классе ObjectFactory в том же пакете. Класс ObjectFactory создается для каждого пакет, в который XJC генерирует некоторые файлы. Имя метода полученных из имен элементов XML/типа, и сообщается об ошибке, если два элементы/типы пытаются создать одно и то же имя метода.

Тем не менее, у вас есть два варианта.

Во-первых, нужно определить внешний XML-привязку, подобный этому

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

В сгенерированном классе ObjectFactory это создаст два метода под названием createTypeBioSampleSet и createTypeTargetBioSampleSet (JAXB добавит имя, которое вы указываете к слову create), которое можно использовать для создания BioSampleSet и TargetBioSampleSet объектов.

(Нет необходимости определять привязку для обоих типов.)

Я не совсем уверен, почему JAXB отказывается генерировать классы из данной схемы, но когда я указал только одну привязку (например, для BioSampleSet), другой тип factory был назван как createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse, поэтому Я думаю, JAXB задохнулся от этого длинного идентификатора метода, потому что ему как-то удалось создать тот же самый для обоих типов. Я думаю, что это некоторые детали реализации в JAXB.

Другое решение - создать базовый тип для BioSampleSet и использовать его в обоих местах, таких как

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

Лучшим решением было бы удалить все анонимные объявления типа из вашей схемы. Если вы можете это сделать, сделайте это, потому что эта схема выглядит как беспорядок (по крайней мере для меня).