【问题标题】:Remove intermediate class when generating code from schema从模式生成代码时删除中间类
【发布时间】:2013-08-15 06:06:22
【问题描述】:

假设我们在 XSD 中定义了一个集合类型

<xs:complexType name="Foos">
  <xs:sequence>
    <xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
      <xs:complexType>
        <xs:all>
          <xs:element name="bar" type="xs:string"/>
          <xs:element name="baz" type="xs:string"/>
        </xs:all>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

当使用 XJC 从中生成 Java 代码时,类型大致转换为

public class Foos {
  public List<Foos.Foo> getFoos();

  public static class Foo {
    public String getBar();
    public String getBaz();
  }
}

由于集合类型是其他类型的一部分,例如文档的根,生成代码的客户端代码看起来有点像这样

for(Foo foo : document.getFoos().getFoos())
{
  //do something
}

有没有什么方法可以让客户端代码不那么难看,而无需手动编写包装器?

应该是这样的

for(Foo foo : document.getFoos())
{
  //do something
}

谢谢

【问题讨论】:

    标签: xml jaxb xsd xjc


    【解决方案1】:

    更新

    人们编写了一些 XJC 插件来生成 @XmlElementWrapper 注释,而不是使用额外的包装类。


    原始答案

    您也可以自己创建带有@XmlElementWrapper 的类,并通过执行以下操作让生成的类引用它:

    文档

    您可以手工制作自己的 Document 类以获得所需的行为。您可以通过利用 @XmlElementWrapper 注释来获取分组元素来获得您正在寻找的行为。

    package forum18247182;
    
    import java.util.*;
    import javax.xml.bind.annotation.*;
    
    public class Document {
    
        private List<Foos.Foo> foos = new ArrayList<Foos.Foo>();
    
        @XmlElementWrapper
        @XmlElement(name="foo")
        public List<Foos.Foo> getFoos() {
            return foos;
        }
    
    }
    

    XML 架构 (schema.xsd)

    这是一个基于您的片段的扩展 XML 模式,我将使用它。

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.example.org/schema" 
        xmlns="http://www.example.org/schema"
        elementFormDefault="qualified">
    
        <xs:element name="document" type="Document"/>
    
        <xs:complexType name="Document">
            <xs:sequence>
                <xs:element name="foos" type="Foos"/>
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="Foos">
            <xs:sequence>
                <xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:all>
                            <xs:element name="bar" type="xs:string" />
                            <xs:element name="baz" type="xs:string" />
                        </xs:all>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    
    </xs:schema>
    

    从 XML Schema (binding.xml) 生成 Java 模型时利用现有类

    我们将使用一个外部绑定文件来表明在类生成期间我们希望将现有类用于称为Document 的复杂类型。

    <jxb:bindings 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
        version="2.1">
    
        <jxb:bindings schemaLocation="schema.xsd">
            <jxb:bindings node="//xs:complexType[@name='Document']">
                <jxb:class ref="forum18247182.Document"/>
            </jxb:bindings>
        </jxb:bindings>
    </jxb:bindings>
    

    XJC 通话

    我们将使用-b 选项来指定我们的绑定文件。我们还将使用-p 选项强制生成的类的包名称与我们的Document 类的名称匹配。我们还可以使 Document 类的包名与从 XML 模式生成类的包名相匹配。

    xjc -b binding.xml -p forum18247182 schema.xsd
    

    演示代码

    package forum18247182;
    
    import javax.xml.bind.*;
    import javax.xml.transform.stream.StreamSource;
    import forum18247182.Foos.Foo;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance("forum18247182");
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StreamSource xml = new StreamSource("src/forum18247182/input.xml");
            Document document = unmarshaller.unmarshal(xml, Document.class).getValue();
    
            for(Foo foo : document.getFoos())
            {
              System.out.println(foo);
            }
        }
    
    }
    

    输出

    下面是运行演示代码的输出:

    forum18247182.Foos$Foo@51f3336e
    forum18247182.Foos$Foo@35b5a4ca
    

    【讨论】:

    • 太棒了 - 非常感谢。这让我发疯了!
    猜你喜欢
    • 2016-09-04
    • 2011-07-30
    • 2010-11-13
    • 2011-03-29
    • 2018-05-26
    • 2015-11-11
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多