Генерация классов Java из XMLSchema.xsd с использованием JAXB
Я использую jaxb для создания классов Java из XML-схемы. Схема импортирует XMLSchema.xsd, а ее содержимое используется в качестве элемента в документе.
Если я удаляю импорт и ссылку на "xsd: schema" соответственно, то компилятор связывания успешно генерирует классы. Если я этого не сделаю, то это приведет к следующим ошибкам, которые будут одинаковыми, если я попытаюсь сгенерировать классы Java только из XMLSchema.xsd!
> C:\Users\me>"%JAXB%/xjc" -extension -d tmp/uisocketdesc -p uis.jaxb uisocketdesc.xsd -b xml_binding_test.xml -b xml_binding_test_2.xml
-b xml_binding_test_3.xml
parsing a schema...
compiling a schema...
> [ERROR] A class/interface with the same name "uis.jaxb.ComplexType" is already in use. Use a class customization to resolve this conflict.
line 612 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "ComplexType" is generated from here.
line 440 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] A class/interface with the same name "uis.jaxb.Attribute" is already in use. Use a class customization to resolve this conflict.
line 364 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "Attribute" is generated from here.
line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] A class/interface with the same name "uis.jaxb.SimpleType" is already in use. Use a class customization to resolve this conflict.
line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "SimpleType" is generated from here.
line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] A class/interface with the same name "uis.jaxb.Group" is already in use. Use a class customization to resolve this conflict.
line 930 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "Group" is generated from here.
line 727 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] A class/interface with the same name "uis.jaxb.AttributeGroup" is already in use. Use a class customization to resolve this conflict.
line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "AttributeGroup" is generated from here.
line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] A class/interface with the same name "uis.jaxb.Element" is already in use. Use a class customization to resolve this conflict.
line 721 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Relevant to above error) another "Element" is generated from here.
line 647 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1020 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 364 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 2278 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 2222 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 930 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 727 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 440 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 612 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1026 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 1062 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] Two declarations cause a collision in the ObjectFactory class.
line 647 of "http://www.w3.org/2001/XMLSchema.xsd"
> [ERROR] (Related to above error) This is the other declaration.
line 721 of "http://www.w3.org/2001/XMLSchema.xsd"
Failed to produce code.
8 ответов
Борьба с такими вещами также, для меня это проблема чувствительности к регистру и одно и то же имя для проблемы элемента и атрибута (иногда через наследование). Для второй проблемы я использую внешний файл привязки, который содержит что-то вроде этого:
<jaxb:bindings node="//xs:complexType[@name='AbstractGriddedSurfaceType']//xs:attribute[@name='rows']">
<jaxb:property name="rowCount"/>
</jaxb:bindings>
Для проблем чувствительности к регистру вы можете использовать аргумент xjc -XautoNameResolution, версия maven <args><arg>-B-XautoNameResolution</arg></args>
, но это не работает для элементов-оболочек, поэтому для них вам нужно написать настройки jaxb, как упомянуто выше, ... а если вам не повезло, как мне:) вам может понадобиться использовать локальную копию xsd и исправить дубликаты вручную.
Изменить Найдено другое решение для проблемы чувствительности к регистру, когда переименование имени элемента недостаточно:
<jaxb:bindings node=".//xs:element[@name='imageDatum'][@type='gml:ImageDatumPropertyType']">
<jaxb:property name="imageDatumInst"/>
<jaxb:factoryMethod name="imageDatumInst" />
</jaxb:bindings>
Удачи, Надеюсь это поможет.
Вы можете успешно заставить JAXB сгенерировать код для XML-схемы xsd (как минимум) двумя способами. Проблема, с которой вы столкнулись, связана с тем, что некоторые типы и элементы схемы имеют одинаковые имена.
Первый вариант позволяет избежать конфликтов имен, применяя одно или несколько преобразований имен XML к сгенерированным именам классов. Вот пример внешнего файла привязки, который будет делать это:
<jxb:bindings version="2.1"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
<jxb:bindings schemaLocation="XMLSchema.xsd">
<jxb:schemaBindings>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Этот подход работает (вы можете применить другие преобразования, которые будут работать так же хорошо, но я видел эту технику снова и снова в документации), но я думаю, что она дает ужасные результаты. Например, в этом случае есть сгенерированный класс с именем ElementElement
,
Второй подход использует настройку класса, как предлагается в выводе xjc. На самом деле все проблемные классы, кроме одного, имеют свойство abstract="true"
установить в соответствующем типе схемы. Поэтому для меня имеет смысл добавлять имя класса к "Абстрактному", т.е. AbstractElement
, Остальные Attribute
класс не является абстрактным, но xs:element
названный attribute
генерирует класс расширения с пустым телом. Поэтому я назвал это BaseAttribute
, Вот определение внешней привязки, которое я использовал:
<jxb:bindings version="2.1"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc">
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
<jxb:bindings schemaLocation="XMLSchema.xsd">
<jxb:schemaBindings>
<jxb:package name="org.w3.xmlschema"/>
</jxb:schemaBindings>
<jxb:bindings node="//xs:complexType[@name='complexType']">
<jxb:class name="AbstractComplexType"/>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='group']">
<jxb:class name="AbstractGroup"/>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='attributeGroup']">
<jxb:class name="AbstractAttributeGroup"/>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='simpleType']">
<jxb:class name="AbstractSimpleType"/>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='element']">
<jxb:class name="AbstractElement"/>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[@name='attribute']">
<jxb:class name="BaseAttribute"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
На мой взгляд, это дает более сгенерированные имена классов и успешно компилирует схему.
Я также рекомендовал бы использовать отдельную компиляцию для XML Schema.xsd и хранить ее в файле jar для дальнейшего использования на случай, если эта проблема возникнет снова при компиляции другой схемы. Ответы на этот вопрос описывают как.
Другой вариант - удалить параметр -p, чтобы классы генерировались в разных пакетах.
Похоже, ваша схема сломана. XJC чрезвычайно требователен к этим вещам и может потерпеть неудачу в вещах, которые пропускают другие инструменты.
Вместо того, чтобы анализировать ошибки XJC, мне проще сначала запустить схему через проверку качества схемы AlphaWorks. Это дает хороший, читаемый человеком (ну, в любом случае, читаемый разработчиком) вывод о том, что не так. Если все пройдет нормально, у вас будет гораздо больше шансов пройти через XJC.
Я столкнулся с той же проблемой при создании объектов из.wsdl с использованием cxf. Решение для меня заключается в использовании -autoNameResolution, как следует из сообщения об ошибке. Конфигурация Maven:
<wsdlOption>
<wsdl>${basedir}/test.wsdl</wsdl>
<extraargs>
<extraarg>-b</extraarg>
<extraarg>http://www.w3.org/2001/XMLSchema.xsd</extraarg>
<extraarg>-autoNameResolution</extraarg>
</extraargs>
<packagenames>
<packagename>test.wsdl</packagename>
</packagenames>
</wsdlOption>
Я наткнулся на ту же ошибку и удалил <generatePackage></generatePackage>
полностью. Это решило мою проблему.
Я попытался следовать, и это работало на меня:
<jxb:bindings schemaLocation="ClaimActivity-ACORD.xsd">
<jxb:schemaBindings>
<jxb:package name="x.x.x.x" />
</jxb:schemaBindings>
<jxb:bindings node="//xsd:complexType[@name='ConstructionType']">
<jxb:class name="AbstractConstructionType" />
</jxb:bindings>
<jxb:bindings node="//xsd:complexType[@name='ItemDefinitionType']">
<jxb:class name="AbstractItemDefinitionType" />
</jxb:bindings>
<jxb:bindings node="//xsd:complexType[@name='LocationType']">
<jxb:class name="AbstractLocationType" />
</jxb:bindings>
<jxb:bindings node="//xsd:complexType[@name='TaxFeeType']">
<jxb:class name="AbstractTaxFeeType" />
</jxb:bindings>
<jxb:bindings node="//xsd:complexType[@name='DeductibleType']">
<jxb:class name="AbstractDeductibleType" />
</jxb:bindings>
<jxb:bindings node="//xsd:complexType[@name='RegistrationType']">
<jxb:class name="AbstractRegistrationType" />
</jxb:bindings>
</jxb:bindings>
Вы можете использовать xjc, который поставляется с JDK1.6. Также вы можете попробовать XML для Java, обратитесь к этой статье.