将多个命名空间 XSD 转换为 Java
Converting multiple namespaces XSD to Java
当我需要将 XSD 转换为 java 时,我总是使用 JAXB。要在 java 上自动执行 XSD 更新,项目 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
包含用于 JAVA 8+ 的 LocalDateTime 适配器以避免 joda.time。源已生成到包名称 com.example.schema
下的 java target
文件夹中。简单 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 多个文件)。
我正在寻找一些方法将不同的命名空间源放在不同的包下,但到目前为止没有成功。
我相信您可以微调每个命名空间的包名称。
我会尝试两件事:
- 从插件中删除“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>
示例取自插件 documentation(向下滚动到第 6 节使用 XML Java 绑定文件)
正如 Babis Routis 在回答中所建议的那样,我最终使用了 jaxb 绑定文件。我的模式包含很多文件,所以我不想手动操作。为了自动化我编写了 sh 脚本的过程:
bfile=bindings.xjb
binding='\t<jxb:bindings schemaLocation="%s" node="//xsd:schema">\n\t\t<jxb:schemaBindings>\n\t\t\t<jxb:package name="%s"/>\n\t\t</jxb:schemaBindings>\n\t</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 没有版本 - 它会转到主包。要使其正常工作,需要从 pom.xml
中删除 packageName
并将其添加到绑定配置中。
当我需要将 XSD 转换为 java 时,我总是使用 JAXB。要在 java 上自动执行 XSD 更新,项目 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
包含用于 JAVA 8+ 的 LocalDateTime 适配器以避免 joda.time。源已生成到包名称 com.example.schema
下的 java target
文件夹中。简单 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 多个文件)。
我正在寻找一些方法将不同的命名空间源放在不同的包下,但到目前为止没有成功。
我相信您可以微调每个命名空间的包名称。
我会尝试两件事:
- 从插件中删除“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>
示例取自插件 documentation(向下滚动到第 6 节使用 XML Java 绑定文件)
正如 Babis Routis 在回答中所建议的那样,我最终使用了 jaxb 绑定文件。我的模式包含很多文件,所以我不想手动操作。为了自动化我编写了 sh 脚本的过程:
bfile=bindings.xjb
binding='\t<jxb:bindings schemaLocation="%s" node="//xsd:schema">\n\t\t<jxb:schemaBindings>\n\t\t\t<jxb:package name="%s"/>\n\t\t</jxb:schemaBindings>\n\t</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 没有版本 - 它会转到主包。要使其正常工作,需要从 pom.xml
中删除 packageName
并将其添加到绑定配置中。