Вы можете успешно заставить 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 для дальнейшего использования на случай, если эта проблема возникнет снова при компиляции другой схемы. Ответы на на этот вопрос описывают как.