2010-03-15 68 views
16

我正在使用JAXB和xjc将我的XML模式编译为Java类。我不想手动编辑这个生成的类。我有XML架构这样的:如何使用xjc和自定义绑定生成XMLElementWrapper注释

<xs:element name="root"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element name="items"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element ref="item" /> 
      </xs:sequence> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

的XJC生成类别Items仅包含Item对象的列表。是否有机会省略课程Items,并在Root课程中直接列出Item个对象?

我知道这可以用@XMLElementWrapper注释完成,但我不知道如何告诉xjc创建这样的。

感谢您的任何建议!

最好的问候, 马库斯

回答

11

Bjarne的汉森开发的XJC一个插件,能够照顾这。不幸的是,原始实现的链接现在已经死亡。然而,Dmitry Katsubo在github上有一个项目,它基于Bjarne的原始代码并进行了一些额外的改进。

https://github.com/dmak/jaxb-xew-plugin


(仅供参考:原始链接,现在死了:http://www.conspicio.dk/blog/bjarne/jaxb-xmlelementwrapper-plugin

+0

托马斯,谢谢。此链接是我见过的关于此主题的第一个正确内容。 – mahonya 2012-03-19 14:26:57

+0

我一直在尝试使用该插件,但无济于事。不知道这是否与xjc 2.2.4兼容(这是我目前所拥有的)。另外,我没有jaxb-xjc.jar(xjc是JDK7工具的一部分)。最后,我想从命令行调用xjc,每个人都非常熟悉如何操作([Kohsuke Kawaguchi](http://weblogs.java.net/blog/kohsuke/archive/2005/06/writing_a_plugi.html )说:“你也可以通过命令行完成它,但它不是很漂亮。”)为什么我们不能只有一个jaxb:annotation来告诉xjc跳过一个级别,即只生成一个'@ XmlElementWrapper'? – 2012-03-22 18:38:18

+0

请注意,我的答案来自两年前 - 当时我使用了该插件,它运行良好,但现在可能已过时。 – Thomas 2012-03-23 00:40:26

8

首先让分手您的架构,以便有没有产生内部类:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified"> 
    <xs:element name="root" type="Root" /> 

    <xs:complexType name="Root"> 
     <xs:sequence> 
      <xs:element name="items" type="Items" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="Items"> 
     <xs:sequence> 
      <xs:element name="item" type="xs:string" maxOccurs="unbounded" /> 
     </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

您仍然可以获得额外的课程,但不是全部在一个文件中。现在你想添加一个部分到你的版本来使用jaxb-xew-plugin。我使用Maven,所以对我来说,这看起来像:

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <version>0.8.2</version> 
    <executions> 
     <execution> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
      <configuration> 
       <args> 
        <arg>-no-header</arg> 
        <arg>-Xxew</arg> 
        <arg>-Xxew:instantiate lazy</arg> 
        <arg>-Xxew:delete</arg> 
       </args> 
       <plugins> 
        <plugin> 
         <groupId>com.github.jaxb-xew-plugin</groupId> 
         <artifactId>jaxb-xew-plugin</artifactId> 
         <version>1.0</version> 
        </plugin> 
       </plugins> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 

如果你开始使用命名空间,使您的生成的类有包名,离开关-Xxew:delete标志,因为有我最近固定它被删除的错误它不应该的对象。或者,您可以从github获取代码并将其用作1.1-SNAPSHOT。

当我这样做,我得到的代码生成,我认为你正在寻找:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Root", propOrder = { 
    "items" 
}) 
public class Root { 

    @XmlElementWrapper(name = "items", required = true) 
    @XmlElement(name = "item") 
    protected List<String> items; 

    public List<String> getItems() { 
     if (items == null) { 
      items = new ArrayList<String>(); 
     } 
     return items; 
    } 

    public void setItems(List<String> items) { 
     this.items = items; 
    } 

}