JAXBを使用して、さまざまな/動的な名前を持つ要素を非整列化する
-
08-07-2019 - |
質問
次のようなノードを持つXMLドキュメントを解析しています:
<objects>
<dog>
<data1>...</data1>
<data2>...</data2>
<data3>...</data3>
</dog>
<cat>
<data1>...</data1>
<data2>...</data2>
<data3>...</data3>
</cat>
</objects>
要素data1、data2、data3は常に一貫しています。親タグのみが異なります。私のオブジェクトモデルには、これらすべてのケースを表す単一のオブジェクトがあります。要素の名前を事前に知ることなく、JAXBにこのケースを処理させるにはどうすればよいですか?
@XMLAnyElementはすべてのオブジェクトに一致しますが、適切なタイプのオブジェクトを作成しません。オブジェクトの代わりにNodeオブジェクトのリストを取得します。私のオブジェクトは現在次のようなものです:
public class MyObject {
protected String otherData;
@XmlAnyElement
@XmlElementWrapper(name = "objects")
protected List<MyChildObject> childObjects;
}
public class MyChildObject {
protected String data1;
protected String data2;
protected String data3;
}
<object type="dog">
要素を使用するように着信XML形式を変更する以外に、このケースを処理する方法はありますか?
解決
名前が本当に動的である場合、JAXBがこれらを支援するとは思わない。定義された数のさまざまな要素名がある場合は、提案されている他の投稿のような継承を使用できます。要素と名前の数が不明な場合は、次のようなものを使用することをお勧めします。
@XmlMixed
@XmlAnyElement
public List<Object> getObjects() {
return objects;
}
これにより、要素は単なるDOM要素になります。その後、JAXBをもう一度使用して、各要素からカスタムタイプに移動できます。
それは、JAXBを使用する必要がある場合です。このようなデータに直接SAXまたはDOM APIを使用する方が簡単な場合があります。 JAXBは、スキーマとして表現できる適切に定義されたデータを対象としています。
他のヒント
継承を使用できます:
@XmlRootElement(name = "dog")
public class MyDogObject extends MyChildObject {
//nothing here
}
@XmlRootElement(name = "cat")
public class MyCatObject extends MyChildObject {
//nothing here
}
この方法では、同じオブジェクトタイプMyChildObject
を処理しながら、XML構造を柔軟に制御できます。別の利点は、将来特定のdog / cat XMLノードを定義する必要があることです-予想どおり、それらは対応するサブクラスにマップできますが、他のサブクラスにはマップできません。