1

かなり複雑なデータ構造を持っているため、正しくアンマーシャリングできないようです。

@XmlRootElement
class Tree {
  @XmlID
  private String id;

  @XmlJavaTypeAdapter(type=TreeFooAdapter.class)
  Map<Tree, Foo> fooMap;
}

class Foo {
  @XmlID
  private String id;
}

私は2つの別々の木を持っています。2 つのノード (各ツリーから 1 つ) をペアにして、Foo のインスタンスに関連付けることができます。fooMap は、特定のツリー ノードがペアになっている他のノードと、結果として得られる Foo のインスタンスを追跡するために使用されます。

TreeFooAdapter は非常に単純ですが、ID 参照を使用することに注意してください。

public class TreeFooAdapter extends XmlAdapter<TreeFooAdapter.MapType, Map<Tree, Foo>> {
  public static class MapType {
    public static class MapEntry {
      @XmlAttribute
      @XmlIDREF
      public Tree key;
      @XmlAttribute
      @XmlIDREF
      public Foo value;
    }
    // etc...
  }

  // Standard drill for marshal/unmarshal...
}

問題: 前方参照が機能しません! アンマーシャリング時、XML で最初に来る Tree は、その fooMap に null キーを持ちます。2 つのツリーは相互に参照しているため、これを回避するために XML の順序を変更することはできません。

を取得/設定するためのプライベートメソッドがあるハックを試しましたList<TreeFooMapEntry>が、同じ結果が得られます。

Map または List に含まれている場合、JAXB が前方 ID 参照を処理できないのはなぜですか? また、これを解決するにはどうすればよいですか?

4

2 に答える 2

0

今回はうまくいくように見える別のハックを試しました。トリックには次のものが含まれます。

  • fooMap を TreeFooAdapter.MapType に変換するプライベート getter/setter ペアを作成します
  • XmlID を TreeFooAdapter.MapType に追加し、getter に XmlIDREF のアノテーションを付けます
  • TreeFooAdapter.MapType のインスタンスの静的セットを維持する
  • Tree と Foo のすべてのインスタンスをマーシャリングした後、インスタンスの Set もマーシャリングします。

これにより、はるかにクリーンな XML が生成されます。ツリーは fooMap の単純な IDREF でマーシャリングされ、XML ファイルの最後は TreeFooAdapter.MapTypes の長いリストであり、それ自体が IDREF のペアのリストです。マーシャリング/アンマーシャリングを複数回行う場合は、インスタンスの静的 Set をクリーンアップするように注意する必要があります。

于 2012-08-31T14:09:52.513 に答える
0

これに触発された(恐ろしい、ひどい、醜い)回避策を見つけまし。私は基本的に PhoneNumberAdapter クラスを一般化して、「識別可能な」もの、つまり一意の ID (つまり、Foo と Tree の両方) を処理できるようにしました。AdaptedPhoneNumber クラスの代わりに、ラップされる実際のオブジェクト (最初に検出されたとき) またはその ID のみ (後続の検出時) を含む ObjectWrapper Bean があります。TreeFooAdapter の MapEntry クラスは、XmlIDREF を持つ代わりに、私の IdentifiableAdapter を XmlJavaTypeAdapter として指定します。

これにより、非常にひどい、読み取り不能な XML が作成されますが、少なくとも機能します。それでも、これは JAXB のバグのようです。苦労してデバッグした後でも、適応された Map クラス内で XmlIDREF が機能しない理由をまだ理解できていません。

于 2012-08-30T14:54:59.710 に答える