Генерация классов 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, обратитесь к этой статье.

Другие вопросы по тегам