2017-01-26 9 views
0

残りの呼び出しから返されたXmlをPOJOにアンマーシャリングしようとしています。しかしながら、1つの呼び出しは、異なるルート要素を有する異なるタイプの文書を返すことができる。ルート要素に依存するJaxbアンマーシャリング

<obj1> ... </obj1> 
<obj2> ... </obj2> 

私は、一般的な機能使用して非整列化:私は別の根のそれぞれのためのクラスを分離するために作成しましたが、私は、私はルート要素の種類を確認することができますかわからない

private <T> T unmarshal(String xml, Class<T> clazz) { 
    JAXBContext jc = JAXBContext.newInstance(clazz); 
    return clazz.cast(jc.createUnmarshaller().unmarshal(new StringReader(xml)); 
} 

をし、私のunmarshall関数を正しい型で呼び出すのですか?

if rootElement.equals("obj1") 
    Obj1 obj = unmarshal(xml, Obj1.class) 
else if rootElement.equals("obj2") 
    Obj2 obj = unmarshal(xml, Obj2.class) 

JaxBを使用してルート要素の条件チェックを行う方法はありますか?

答えて

0

はい可能です。

  1. @XmlRootElementで可能なルートクラスをそれぞれ宣言します。
  2. 可能なすべてのルートクラスを使用してJAXBContextを作成します。

    JAXBContext jc = JAXBContext.newInstance(Class...)

  3. その後、

    Object obj = unmarshal(xml); if(obj instanceof Root1) { // cast to Root1 object } else obj instanceof Root2) { // cast to Root2 object }

0

これを行うには良い方法があるかどうか私は知らないが、私は1つを見つけることができませんでした。この問題を解決するために 私は、ルート要素の両方のタイプを含むオブジェクト作成:半一般的な方法でアンマーシャリングするために

@Data 
public class compositionObject { 
private Obj1 obj1; 
private Obj2 obj2; 

public compositionObject(final Object obj) { 
    if(obj instanceof Obj1) { 
     this.obj1 = obj1; 
    } else if(obj instanceof Obj2) { 
     this.obj2 = obj2; 
    } else { 
     throw new IllegalArgumentExcepion("not supported"); 
    } 
} 

を:@XmlElementDecl@XmlRegistryを使用して

private Object unmarshal(String xml, Class<?>... clazzes) { 
    JAXBContext jc = JAXBContext.newInstance(clazzes); 
    return clazz.cast(jc.createUnmarshaller().unmarshal(new StringReader(xml)); 
} 

は私の意図した動作を与えるものではありませんJAXBElement<CompositionObject>ではなくJAXBElement<Obj1>が返されるためです。以下は動作しませんでした:

private final static QName OBJ1_QNAME = new QName("", "obj1"); 
private final static QName COMP_OBJ_QNAME = new QName("", "compositionobj"); 

@XmlElementDecl(namespace = "", name = "obj1") 
public JAXBElement<CompositionObject> createObj1(final Obj1 value) { 
    final CompositionObject compObj = new CompositionObject(); 
    comPbj.setObj1(value); 
    return new JAXBElement<CompositionObject>(COMP_OBJ_QNAME, CompositionObject.class, null, value); 
} 

質問:@XmlRegistry - how does it work?答えを@XmlRegistryがそのように使用することはできません理由。

+0

'@ XmlRootElement'自体で、アンマーシャリングした後に正しいオブジェクトインスタンスを取得できます。私は問題はあなたが '@ XmlRootElement'としてそれらをdelcaredしていないことだと思います。あなたはなぜ私の答えで上記のポイント3を使って直接ルート要素オブジェクトにキャストできないのかを詳しく説明できますか? – ulab

+0

Obj1とObj2モデルクラスの両方に '@XmlRootElement'というアノテーションが付けられています。私は問題文があいまいであると思います。私は、複数の '@XmlRootElement'をとり、それらを単一のオブジェクトに変換できるようなカスタム解析ロジックを作成したかったのです。私はこれをやりたかったのです。なぜなら、私が外部のRESTサービスに行っていた呼び出しが、同じ呼び出しのために異なるタイプのオブジェクトを返すことができるからです。 – Niru

関連する問題