1

.NET で IXmlSerializable を使用して可能なのと同じ方法で、JAXB で XML シリアル化をカスタマイズする方法はありますか? (つまり、XmlReader/Writer に相当するものを使用して、オブジェクトのシリアル化を直接制御する機能)。

私は XmlAdapter と @XmlJavaTypeAdapter を見てきましたが、それらは型をシリアライズ可能なフォームとの間で変換するために使用されているように見えますが、これは私が望むものではありません。

更新:特に、内部 XML を逆シリアル化する方法をプログラムで正確に決定するルート オブジェクトの逆シリアル化をカスタマイズしたいと思います (たとえば、既知の型の特定のセットで jaxb unmarshaller を作成します)。

更新: この問題を解決する方法を見つけましたが、これは非常に厄介なハックであるため、おそらく他の投稿者によって提案された解決策の 1 つを使用します。

4

3 に答える 3

6

OK、それでなんとかこれを機能させることができましたが、Fabianとbasszeroが述べたように、問題を回避するより高いレベルの方法を見つけると思うほど厄介な解決策です. 次のコードの考え方は、シリアル化するデータへの一般的なシリアル化可能な参照を作成することです。これは、シリアル化をプログラムで実行するための JAXB Java タイプ アダプターと、結果の XML を格納する文字列フィールドを保持します。

注: コードは表示用に大幅に簡略化されています...

// Create an instance of this class, to wrap up whatever you want to custom-serialize
@XmlRootElement
public static class SRef
{
    public SRef() { }
    public SRef(Object ref)
    {
        this.ref = ref;
    }

    @XmlJavaTypeAdapter(SRefAdapter.class)
    public Object ref;
}

// This is the adapted class that is actually serialized 
public static class SRefData
{
    // This is a hint field to inform the adapter how to deserialize the xmlData
    @XmlAttribute
    public String hint;

    // This contains the custom-serialized object
    @XmlElement
    public String xmlData;
}

    // Converts an object to and from XML using a custom serialization routine
public static class SRefAdapter extends XmlAdapter<SRefData, Object>
{
    @Override
    public SRefData marshal(Object value) throws Exception
    {
        if (value instanceof MyType)
        {
            SRefData data = new SRefData();
            data.xmlData = doSomeSpecificSerialization(value);
            data.hint = "myType";
            return data;
        }
        throw new IllegalArgumentException("Can't serialize unknown object type " + value.getClass());
    }

    @Override
    public Object unmarshal(SRefData refData) throws Exception
    {
        if (refData.hint.equals("myType"))
        {
            return doSomeSpecificDeserialization(refData.xmlData);
        }
        throw new IllegalArgumentException("Unhandled hint value in SRefData: " + refData.hint); 
    }
}
于 2009-02-09T10:38:21.147 に答える
1

ルート ノード自体から得られた何らかの属性または知識に基づいて、ルート ノードに 2 つの異なる xml ノード/ツリーのセットを含めたいと思われます。

私は、最初にスキーマ (xsd) を作成し、次に Java ソースを生成することによって JAXB を使用する傾向がありますが、これは決して変更しません。スキーマと再生成のみを変更します。ソースに注釈を付けることによって、JAXB を他の方法で使用することはできないことに気付きました。あなたがスキーマなら... 続きを読む

これを考慮してください:http://www.w3schools.com/Schema/schema_complex_indicators.asp

アンマーシャラーを切り替えるのではなく、両方の xml 定義を含めるだけです。それらは関係なく解析され、ルートノードでチェックする属性を介してプログラム制御フローを変更できます。

于 2009-02-08T23:08:22.477 に答える
1

I'm not sure I fully understand what your goal is, but maybe you could do what you want to do programatically inside the no-args constructor of your root object, which will be called to instantiate the object when it is unmarshalled.

于 2009-02-08T22:37:11.037 に答える