问题描述
运行以下 xjc 命令会引发错误:
Running the following xjc command raises an error :
$ 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 中的冲突是什么,但我不明白当前模式中的冲突在哪里.
Although I understand the JAXB bindings and what are is conflict in XJC, I don't understand where is the conflict in the current schema.
我应该如何解决这个问题?
how should I fix this ?
谢谢,
皮埃尔
更新:这里是错误的上下文:
update: here is the context of the errors:
$ curl -s "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd" | sed 's/^[ ]*//' | 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
推荐答案
我将引用 最官方的非官方网络上的 JAXB 指南.
当模式包含相似的元素/类型名称时,它们可以导致两个声明导致 ObjectFactory 中的冲突类"错误.更准确地说,对于所有类型和许多元素(确切地说,哪些元素获得了工厂,哪些没有很难解释),XJC 在 ObjectFactory 类上生成一个方法在同一个包中.ObjectFactory 类是为每个XJC 生成一些文件的包.该方法的名称是派生自 XML 元素/类型名称,如果有两个则报错元素/类型尝试生成相同的方法名称.
也就是说,您有两个选择.
That said, you have two options.
首先是定义一个这样的外部绑定XML
The first is to define an external binding XML like this
<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
对象.
In the generated ObjectFactory
class this will create two methods called createTypeBioSampleSet
and createTypeTargetBioSampleSet
(JAXB will append the name you specify to the word create
) that can be used to produce BioSampleSet
and TargetBioSampleSet
objects.
(没有必要为两种类型定义绑定.)
(It's not necessary to define a binding for both types.)
我不完全确定为什么 JAXB 拒绝从给定的模式生成类,但是当我只指定一个绑定(例如对于 BioSampleSet
)时,另一种类型的工厂方法被命名为 createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse
所以我认为 JAXB 被这个长方法标识符阻塞了,因为它以某种方式设法为两种类型创建了相同的标识符.我认为这是 JAXB 中的一些实现细节.
I'm not exactly sure why JAXB refuses to generate classes from the given schema, but when I specified only one binding (for BioSampleSet
for example) then the other type's factory method was named like createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse
so I think JAXB choked on this long method identifier, because it somehow managed to create the same one for both types. I think this is some implementation detail in JAXB.
另一种解决方案是为 BioSampleSet
创建一个基本类型,并像这样在两个位置使用它
The other solution is to create a base type for a BioSampleSet
and use that at both locations like this
<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>
最好的解决方案是从架构中删除每个匿名类型声明.如果你能做到,那就去做吧,因为这个模式看起来一团糟(至少对我来说).
The best solution would be to drop every anonymous type declarations from your schema. If you can do that, do it, because this schema looks like a mess (to me at least).
这篇关于xjc:两个声明导致 ObjectFactory 类中的冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!