web-dev-qa-db-ja.com

@XMLRootElement vs @XmlType

@XMLRootElement@XMLTypeでクラスに注釈を付けることの違いは何ですか? XMLスキーマ内で構造が複数回使用される場合は@XMLTypeでクラスに注釈を付け、1回のみ使用される場合は@XMLRootElementで注釈を付けました-これが最良のアプローチですか?

別の関連する質問をここに含めます。 @XMLTypeアノテーションには、要素が表示される順序を指定するpropOrder属性があります。@XMLRootElementに相当するものはありますか?

これらの注釈をJAX-WS注釈と組み合わせて使用​​して、違いが生じる場合はWebサービスを作成しています。

37
CodeClimber

XmlRootElementXmlTypeの違いはスコープの問題です。この注釈は、XMLの生成に使用されるスキーマの作成を指示しているに過ぎないことに注意してください。 XmlRootElementは、グローバル要素(匿名またはスキーマタイプ)を示します。

<xs:element name=foo type="bar"> </xs:element> <-- schema type

一方、XmlTypeは、ローカル要素(匿名型または複合型)を示すために使用されます。

<xs:complexType name=bar> </xs:complexType> <-- complex type

ここでのローカル/グローバルの主な違いは、オブジェクトが表示されるスキーマの階層と、スキーマタイプまたは複合タイプを宣言するかどうかです。これらのアノテーションの両方のドキュメントは、よく書かれており、例を含んでいます。

XmlRootElement

XmlType

編集:propOrder質問に対処します:ローカル型も宣言している場合、グローバル要素で使用できます:

@XmlRootElement (name="PersonElement")
@XmlType (propOrder={"firstname", "lastname"})
public class People{
    @XmlElement
    public String firstname;
    public String lastname;
}

これにより、次のような結果が得られます。

<xs:element name="PersonElement" type="People"/>
<xs:complexType name="People">
    <xs:sequence>
        <xs:element name="firstname" type="xs:string"/>
        <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
</xs:complexType>
21
DocWatson

XMLスキーマ内で構造が複数回使用される場合は@XMLTypeでクラスに注釈を付け、1回のみ使用される場合は@XMLRootElementで注釈を付けました-これが最良のアプローチですか?

知っておくべきことの1つは、_@XmlRootElement_アノテーションも_@XmlType_アノテーションも必要ないことです。 JPAの_@Entity_と同等ではありません。 JAXB(JSR-222) 実装は、アノテーションなしで使用できます。

以下では、_@XmlRootElement_と_@XmlType_が何をするかを説明します。


_@XmlRootElement_

JAXB実装が、処理中のXML要素のみに基づいてオブジェクトをインスタンス化する必要がある場合があります。 _@XmlRootElement_注釈は、この関連付けを指定する主な手段です。クラスが複数のXML要素に対応する場合は、_@XmlElementDecl_注釈をinsteatで使用する必要があります。

役割#1-ルートオブジェクトの指定

_@XmlRootElement_は、主にルートオブジェクトを指定するために使用されます。これは、JAXB実装がXMLドキュメントの非整列化を開始するときに、インスタンス化するオブジェクトを認識しているためです。ほぼすべての後続の注釈は、親クラスから収集された情報に基づいています。

Foo

_@XmlRootElement(name="root")
public class Foo {

    private String name;

}
_

Bar

_public class Bar {

    private String name;

}
_

[〜#〜] xml [〜#〜]

_<root>
    <name>Jane Doe</name>
</root>
_

デモ

_Foo foo = (Foo) unmarshaller.unmarshal(xml);
Bar bar = unmarshaller.unmarshal(xml, Bar.class).getValue();
_

役割#2-置換グループ

_@XmlElementRef_注釈は、インスタンス化されたオブジェクトのタイプを要素の名前/ URIに委任します。これにより、継承を表すための置換グループの概念へのマッピングが可能になります。

役割#3-任意のコンテンツ

_@XmlAnyElement_を使用すると、XMLドキュメントのワイルドカードセクションをマップできます。 @XmlAnyElement(lax=true)を指定すると、ドメインオブジェクトに関連付けられた要素は、対応するドメインオブジェクトに変換されます。


_@XmlType_

役割#1-スキーマ生成

デフォルトでは、JAXBコンテキストに既知のJavaクラスごとに名前付き複合型が生成されます。_@XmlType_アノテーションを使用してこの型の名前を制御するか、匿名複合体を指定できますタイプは、名前を_""_として指定して生成する必要があります。

役割#2-継承とxsi:type

デフォルトでは、JAXBは_xsi:type_属性を継承インジケーターとして利用します。この属性の値は、_@XmlType_アノテーションで指定した名前と名前空間に対応するか、クラスに基づいてデフォルト設定されます。

役割#3-プロップオーダー

言及したように、_@XmlType_を使用してプロパティの順序を指定できます。

役割#4-ファクトリーメソッド

_@XmlType_を使用すると、デフォルトのコンストラクターの代わりにドメインオブジェクトのインスタンス化に使用できるファクトリークラスやメソッドを指定できます。


別の関連する質問をここに含めます。 @XMLType注釈には、要素の表示順序を指定するpropOrder属性があります。@ XMLRootElementに相当するものはありますか?

いいえ、propOrderアスペクトは_@XmlType_アノテーションに属します。複雑な型は順序を指定する(または順序を指定しない)ので、これは理にかなっています。もちろん、これらの注釈を同時に使用できます。

_@XmlRootElement
@XmlType(propOrder={"foo", "bar"}
public class Root {
    ...
}
_
17
bdoughan