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

アップデート

@XmlElementWrapper追加のラッパー クラスを持つ代わりに、注釈を生成するために作成された XJC プラグインがあります。


元の答え

別の方法として、次のようにして@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、生成されたクラスのパッケージ名を強制的にクラスの名前と一致させますDocumentDocumentクラスのパッケージ名を、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 に答える