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

谢谢

请您参考如下方法:

更新

人们编写了一些 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 架构生成 Java 模型 (binding.xml) 时利用现有类

我们将使用外部绑定(bind)文件来指示在类生成期间我们希望将现有类用于名为 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选项来指定我们的绑定(bind)文件。我们还将使用 -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 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!