#java #xml #maven #xsd #jaxb
#java #xml #maven #xsd #jaxb
Вопрос:
Когда мне нужно было преобразовать XSD в java, я всегда использовал JAXB. Для автоматизации обновлений XSD на java project maven
поставляется в справке jaxb2-maven-plugin
. Стандартная конфигурация pom.xml
для этого разговора выглядит следующим образом:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<configuration>
<clearOutputDir>false</clearOutputDir>
<extension>true</extension>
<arguments>
<argument>-Xfluent-api</argument>
</arguments>
</configuration>
<executions>
<execution>
<id>generate-schema</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>xsd/xsd_location</source>
</sources>
<sourceType>xmlschema</sourceType>
<xjbSources>
<xjbSource>xsd/LocalDateTimeBinding.xjb</xjbSource>
</xjbSources>
<packageName>com.example.schema</packageName>
</configuration>
</execution>
</plugin>
Куда xsd/xsd_location
я помещаю свои файлы XSD и xsd/LocalDateTimeBinding.xjb
содержит адаптер LocalDateTime для JAVA 8 , чтобы избежать joda.time. Исходные тексты были сгенерированы в target
папку java под именем пакета com.example.schema
. С простым XSD все работало отлично. На этот раз у меня сложный вопрос, так что я не знаю, что делать. Проблема связана с несколькими пространствами имен, содержащими одни и те же типы. Пример XSD выглядит следующим образом:
<?xml version='1.0' encoding='UTF-8'?>
<xsd:schema xmlns="http://mydaomain.com/BusinessObjects/Common/AdditionalInformationDataListType/V2" targetNamespace="http://example.com/BusinessObjects/Common/AdditionalInformationDataListType/V2"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns0="http://example.com/BusinessObjects/Common/AdditionalInformationDataType/V1" xmlns:ns1="http://example.com/BusinessObjects/Common/AdditionalInformationDataType/V2">
<xsd:import namespace="http://example.com/BusinessObjects/Common/AdditionalInformationDataType/V1" schemaLocation="../../../../BusinessObjects/Common/AdditionalInformationDataType/V1/AdditionalInformationDataType.xsd"/>
<xsd:import namespace="http://example.com/BusinessObjects/Common/AdditionalInformationDataType/V2" schemaLocation="../../../../BusinessObjects/Common/AdditionalInformationDataType/V2/AdditionalInformationDataType.xsd"/>
<xsd:complexType name="AdditionalInformationDataListType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="additionalInformationDataV1" type="ns0:AdditionalInformationDataType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="additionalInformationDataV2" type="ns1:AdditionalInformationDataType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Проблема в том, что
../../../../BusinessObjects/Common/AdditionalInformationDataType/V1/AdditionalInformationDataType.xsd
и
../../../../BusinessObjects/Common/AdditionalInformationDataType/V2/AdditionalInformationDataType.xsd
находятся в разных папках, разных версиях XSD-типов, в разных пространствах имен, но оба имеют одно и то же имя типа.
Моя текущая конфигурация пытается поместить их в один и тот же пакет, и я получаю сообщение об ошибке, какой файл уже существует. Я не могу изменить XSD (и не хочу этого делать, потому что он содержит более 100 файлов).
Я искал какой-нибудь способ поместить разные источники пространства имен в разные пакеты, но пока безуспешно.
Комментарии:
1. Пожалуйста, не отвечайте на вопрос. Я откатил / отредактировал ваш вопрос и удалил ответ. Добавьте ответ только в раздел ответов.
Ответ №1:
Я полагаю, что вы можете точно настроить имена пакетов для каждого пространства имен.
Я бы попробовал две вещи:
- Либо удалите «packageName» из плагина, либо (лучше)
- Определите имя пакета для каждого пространства имен с помощью файла настройки Jaxb
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--
Change since version 2.0 of the j-m-p:
Note that the schemaLocation path must point to the XSD file
relative to *this* file, rather than the basedir.
-->
<jxb:bindings schemaLocation="../xsd/address.xsd" node="//xsd:schema">
<jxb:schemaBindings>
<jxb:package name="com.example.myschema"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Пример взят из документации по плагинам (прокрутите вниз до раздела 6 с использованием файла привязки XML Java).
Комментарии:
1. Как-то я пропустил эту часть.. Похоже, это то, что мне нужно, но полная схема содержит 3616 файлов XSD, поэтому это займет некоторое время.. Подумываю сделать скрипт bash для генерации привязок, а затем передать их в addon. Позже я обновлю свой прогресс
Ответ №2:
Как предложил Бабис Рутис в ответе, я закончил тем, что использовал файл привязок jaxb. Моя схема содержит много файлов, поэтому я не хотел делать это вручную.. Для автоматизации процесса я написал сценарий sh:
bfile=bindings.xjb
binding='t<jxb:bindings schemaLocation="%s" node="//xsd:schema">ntt<jxb:schemaBindings>nttt<jxb:package name="%s"/>ntt</jxb:schemaBindings>nt</jxb:bindings>n'
echo '<jxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">' > ${bfile}
for fname in $(find . -name '*.xsd' -print)
do
case $fname in
*"/V1/"*)
printf "$binding" "$fname" "com.example.schema.v1" >> ${bfile}
;;
*"/V2/"*)
printf "$binding" "$fname" "com.example.schema.v2" >> ${bfile}
;;
*)
printf "$binding" "$fname" "com.example.schema" >> ${bfile}
;;
esac
done
echo "</jxb:bindings>" >> ${bfile}
Он генерирует каждую версию в разных пакетах на основе пути к каталогу, и если у XSD нет версии — она переходит в основной пакет. Чтобы заставить его работать, необходимо удалить packageName
из pom.xml
и добавить это в конфигурацию привязок.