微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将多个命名空间 XSD 转换为 Java

如何解决将多个命名空间 XSD 转换为 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。源已生成到包名称 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. 从插件中删除“packageName”,或者(更好)
  2. 使用 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 没有版本 - 它会转到主包。要使其工作,需要从 packageName 中删除 pom.xml 并将其添加到绑定配置中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。