11

假设我们在 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
}

谢谢

4

1 回答 1

11

更新

人们编写了一些 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 模式 (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
于 2013-08-19T20:34:09.643 回答