这是我前几天遇到的一个有趣的场景。我最终确实靠自己达成了解决方案。但是,我欢迎您提出任何意见和更好的方法。

需求

我想基于XSD集合使用XJC作为Maven构建的一部分来生成JAXB对象。 。我将使用JAXB-RI 2.1作为实现。

此外,我想确保所有对象都实现没有方法的签名接口(例如MySignature)。另外,我想避免使用XmlGregorianCalendar来代替Joda DataTime(我将通过DateUtilsparse()方法提供一个合适的适配器,称为format())。

最后,我希望能够选择某些对象充当根元素,因此我需要有选择地将@XmlRootElement添加到某些对象,并且我有合适的XPath表达式来定位它们。

我无法对XSD进行任何更改。

方法

步骤1-配置pom.xml

将Maven配置为使用XJC插件,如下所示:



 <build>
    <plugins>
      <plugin>
        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.7.4</version>
        <executions>
          <execution>
            <id>generate-domain1</id>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <strict>false</strict>
              <schemaIncludes>
                <value>domain1.xsd</value>
              </schemaIncludes>
              <bindingIncludes>
                <include>domain1-bindings.xjb</include>
              </bindingIncludes>
              <extension>true</extension>
              <generatePackage>org.example.domain1</generatePackage>
              <generateDirectory>${project.build.directory}/generated-sources/domain1</generateDirectory>
              <args>
                <arg>-Xannotate</arg>
               </args>                  
               <plugins>
                <plugin>
                  <groupId>org.jvnet.jaxb2_commons</groupId>
                  <artifactId>jaxb2-basics</artifactId>
                  <version>0.6.0</version>
                </plugin>
                <plugin>
                  <groupId>org.jvnet.jaxb2_commons</groupId>
                  <artifactId>jaxb2-basics-annotate</artifactId>
                  <version>0.6.0</version>
                </plugin>
              </plugins>
            </configuration>
          </execution>
        </executions>
      </plugin>
   </plugins>
</build>
 


使用专用的执行配置可以允许其他互斥的配置使用不同的目标输出路径构建的XSD。

步骤2-配置绑定

包括以下内容作为src/main/resources/domain1-bindings.xjb

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings
  xmlns:jaxb="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"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:annox="http://annox.dev.java.net"
  xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
  jaxb:extensionBindingPrefixes="xjc annox"
  version="2.1">

  <jaxb:globalBindings>
    <jaxb:serializable uid="1"/>
    <!-- All generated classes must have MySignature interface (supplied in dependencies) -->
    <xjc:superInterface name="org.example.MySignature"/>
    <!-- All temporal fields are implemented as Joda DateTime and use DateUtils as an adapter -->
    <jaxb:javaType
      name="org.joda.time.DateTime"
      xmlType="xs:time"
      parseMethod="org.example.DateUtils.parseDateTime"
      printMethod="org.exmaple.DateUtils.formatDateTime"
      />
  </jaxb:globalBindings>

  <!-- Application of annotations to selected classes within schemas -->

  <!-- org.example.SomeRootType @XmlRootElement -->
  <jaxb:bindings schemaLocation="domain1.xsd" node="/xs:schema">
    <jaxb:bindings node="xs:complexType[@name='SomeRootType']">
      <annox:annotate>
        <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="SomeRootType"/>
      </annox:annotate>
    </jaxb:bindings>
  </jaxb:bindings>

</jaxb:bindings>
 


故障排除

如果遇到臭名昭著的



不支持的绑定命名空间“”。也许您的意思是“ http://annox.dev.java.net”


,那么您需要检查bindings.xjb,以确保您使用的是正确的名称空间URI(已定义)以上)并将其包含在extensionBindingPrefixes中。

#1 楼

<jaxb:javaType />标记会为每个新的javaType定义生成一个新的org.w3._2001.xmlschema.AdapterN类。因此,更好的方法是:


创建扩展XmlAdapter<String, _To_>的类。在其中,您将必须覆盖定义的两个方法。因此,在示例中,该类可能是org.example.DateUtilsAdapter

请改用此标记:

<xjc:javaType
    name="org.joda.time.DateTime"
    xmlType="xs:time"
    adapter="org.example.DateUtilsAdapter" />





评论


\ $ \ begingroup \ $
我有一个带有java.util.Date适配器(JaxbDateAdapter)的示例。来源在这里
\ $ \ endgroup \ $
– Guillaume Husta
2014年1月13日在16:26

#2 楼

我在Eclipse中尝试了您的示例并收到警告:

cvc-complex-type.3.2.2: Attribute 'jaxb:extensionBindingPrefixes' is not allowed to appear in 
 element 'jaxb:bindings'.


当我将URL从2.0更改为2.1时,它删除了警告。

之前:http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd
之后:http://java.sun.com/xml/ns/jaxb/bindingschema_2_1.xsd

<jaxb:bindings
  xmlns:jaxb="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"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:annox="http://annox.dev.java.net"
  xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_1.xsd"
  jaxb:extensionBindingPrefixes="xjc annox"
  version="2.1">