18

非公式ガイドには、(私には)まったく関係がないと思われる記事へのリンクを含むプレースホルダーの回答があります。

XJCを使用してJAXBクラスを生成します。それらのほとんどは期待どおりに相互にマップされますが、一部の要素はにマップされJAXBElement<Foo>ます。これは、サイクルのあるグラフで最も厄介です。Foo要素の親ノードが、JAXBElement<Foo>それ自体に親プロパティを持たないが、サイクルを壊してしまうことがあります。

さまざまな回避策を考えることができますが、誰かがこの動作を私に説明してくれるともっといいでしょう。<Foo>JAXBが要素をJAXBElement<Foo>Fooの代わりにマップすることがあるのはなぜですか?

4

2 に答える 2

11

JAXBElementは、オブジェクトモデルに十分な情報が存在しないユースケースで要素名/名前空間を保持するために使用されます。最も一般的な発生は、置換グループの場合です。

代替グループあり:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="anElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="anElement" type="xs:string"/>

    <xs:element name="aSubstituteElement" type="xs:string" substitutionGroup="anElement"/>

</xs:schema>

生成されます:

package org.example;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "anElement"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElementRef(name = "anElement", namespace = "http://www.example.org", type = JAXBElement.class)
    protected JAXBElement<String> anElement;

    public JAXBElement<String> getAnElement() {
        return anElement;
    }

    public void setAnElement(JAXBElement<String> value) {
        this.anElement = ((JAXBElement<String> ) value);
    }

}

代替グループなし:

置換グループを削除した場合:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org" 
    xmlns="http://www.example.org" 
    elementFormDefault="qualified">

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="anElement"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="anElement" type="xs:string"/>

</xs:schema>

次のクラスが生成されます。

package org.example;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "anElement"
})
@XmlRootElement(name = "root")
public class Root {

    @XmlElement(required = true)
    protected String anElement;

    public String getAnElement() {
        return anElement;
    }

    public void setAnElement(String value) {
        this.anElement = value;
    }

}

アンマーシャリング時にJAXBElementを取得する場合もあります。次の例を比較してください。

于 2010-09-07T14:03:44.630 に答える
0

JAXBElementへのマッピングを回避するには?私はそれが私のために働くこのことをしました:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
           xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
           jaxb:extensionBindingPrefixes="xjc"
           jaxb:version="2.0">

    <xs:annotation>
       <xs:appinfo>
          <jaxb:globalBindings generateValueClass="false">
           <xjc:simple />
          </jaxb:globalBindings>
       </xs:appinfo>
    </xs:annotation>

</xs:schema>

このファイルをxmlファイルに保存し、バインディングファイルとして提供します。

参照リンク

Eclipseを使用してJAXBクラスを生成する場合は、上記のxmlで作成されたバインディングファイルを指定し、以下のように[ベンダー拡張を許可する]をオンにすることを忘れないでください。

ここに画像の説明を入力してください

変更により、xsdをJAXBで生成されたクラスに変換するためにxjcで生成されたクラスのJAXBElementを取り除くことができます。

于 2017-05-11T12:59:14.897 に答える