有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

xml将多个名称空间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。时间源代码已生成到包名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多个文件)

我一直在寻找将不同名称空间源放在不同包下的方法,但到目前为止运气不佳


共 (2) 个答案

  1. # 1 楼答案

    我相信您可以微调每个名称空间的包名称

    我会尝试两件事:

    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(使用XML Java绑定文件向下滚动到第6节)

  2. # 2 楼答案

    正如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,并将其添加到绑定配置中