Генерация классов Java из XMLSchema.xsd с использованием JAXB - PullRequest
19 голосов
/ 09 марта 2010

Я использую 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 ]

18 голосов
/ 17 июля 2012

Борьба с такими вещами также, для меня это проблема чувствительности к регистру и то же имя для проблемы элемента и атрибута (иногда через наследование). Для второй проблемы я использую внешний файл привязки, который содержит что-то вроде этого:

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

Удачи, надеюсь, это поможет.

9 голосов
/ 22 августа 2011

Вы можете успешно заставить 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>

На мой взгляд, это дает более четкие сгенерированные имена классов и успешно компилирует схему.


Я бы также рекомендовал использовать отдельную компиляцию для XMLSchema.xsd и хранить ее в файле jar для дальнейшего использования на случай, если эта проблема возникнет снова при компиляции другой схемы. Ответы на на этот вопрос описывают как.

4 голосов
/ 09 марта 2010

Похоже, ваша схема сломана. XJC крайне требователен к этим вещам и может потерпеть неудачу в вещах, которые пропускают другие инструменты.

Вместо того, чтобы выбирать ошибки XJC, мне проще сначала запустить схему через Проверка качества схемы AlphaWorks . Это дает хороший, читаемый человеком (ну, в любом случае, читаемый разработчиком) вывод о том, что не так. Если все пройдет нормально, у вас будет гораздо больше шансов пройти через XJC.

3 голосов
/ 18 октября 2016

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

2 голосов
/ 22 сентября 2014

У меня возникла такая же проблема при создании объектов из .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>
0 голосов
/ 04 октября 2018

Я столкнулся с той же ошибкой и полностью удалил <generatePackage></generatePackage>. Это решило мою проблему.

0 голосов
/ 19 июля 2015

Я попробовал следующее, и у меня это сработало:

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

0 голосов
/ 30 апреля 2010

Вы можете использовать xjc, который поставляется с JDK1.6. Также вы можете попробовать XML в Java, см. эту статью .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...