xjc: dwie deklaracje powodują kolizję w klasie ObjectFactory
Uruchomienie następującego polecenia xjc powoduje błąd:
$ 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
Chociaż rozumiem powiązania JAXB i co to jest konflikt w XJC, nie rozumiem, gdzie jest konflikt w obecnym schemacie.
Jak mam to naprawić ?Dzięki,
Pierre
Update: oto kontekst błędów:
$ 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
2 answers
Zacytuję z najbardziej oficjalnego nieoficjalnego poradnika na JAXB w sieci.
Gdy Schematy zawierają podobne wyglądające nazwy elementów/typów, mogą result in " dwie deklaracje powodują kolizję w obiekcie Klasa " błędy. Aby być bardziej precyzyjnym, dla każdego z wszystkich typów i wielu elementy (dokładnie jakie elementy mają fabrykę, a co nie jest bitem trudne do wyjaśnienia), XJC produkuje jedną metodę na klasie ObjectFactory w tym samym opakowaniu. Na Klasa ObjectFactory jest tworzona dla każdego pakiet, do którego xjc generuje niektóre pliki. Nazwa metody to pochodzi z nazw elementów/typów XML, a błąd jest zgłaszany, jeśli dwa elementy / typy próbują wygenerować tę samą nazwę metody.
To powiedziawszy, masz dwie opcje.
Pierwszym jest zdefiniowanie zewnętrznego bindowania XML w taki sposób
<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>
W Wygenerowanej klasie ObjectFactory
spowoduje to utworzenie dwóch metod o nazwie createTypeBioSampleSet
i createTypeTargetBioSampleSet
(JAXB doda nazwę określ słowo create
), które może być używane do tworzenia obiektów BioSampleSet
i TargetBioSampleSet
.
(nie jest konieczne definiowanie wiązania dla obu typów.)
Nie jestem do końca pewien, dlaczego JAXB odmawia generowania klas z podanego schematu, ale kiedy podałem tylko jedno powiązanie (na przykład dla BioSampleSet
), wtedy fabryczna metoda drugiego typu została nazwana tak jak createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse
, więc myślę, że JAXB zadławił się tym długim identyfikatorem metody, ponieważ jakoś udało mu się stworzyć ten sam dla obu typów. I myślę, że to jakiś szczegół implementacji w JAXB.
Innym rozwiązaniem jest utworzenie typu bazowego dla BioSampleSet
i użycie go w obu miejscach, jak to
<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>
Najlepszym rozwiązaniem byłoby usunięcie wszystkich anonimowych deklaracji typu ze schematu. Jeśli możesz to zrobić, zrób to, ponieważ ten schemat wygląda jak bałagan(dla mnie przynajmniej).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-18 07:21:53
Usuń pakiet-p w Komendzie
xjc -d src -XautoNameResolution TFMData_Service.xsd
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-05 10:29:22