1

我有一个相当复杂的数据结构,我似乎无法正确解组。

@XmlRootElement
class Tree {
  @XmlID
  private String id;

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

class Foo {
  @XmlID
  private String id;
}

我有两棵独立的树。两个节点(每棵树一个)可以配对并与 Foo 的一个实例相关联。fooMap 用于跟踪给定树节点已与哪些其他节点配对,以及 Foo 结果的哪些实例。

TreeFooAdapter 非常简单,但请注意它使用 ID refs:

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...
}

问题:前向引用不起作用!解组时,无论哪个 Tree 在 XML 中最先出现,其 fooMap 中的键都为空。由于这两棵树相互引用,因此我无法更改 XML 的顺序来解决这个问题。

我尝试了一个 hack,其中我有一个私有方法来获取/设置 a List<TreeFooMapEntry>,但它产生了相同的结果。

为什么当它们包含在 Map 或 List 中时,JAXB 无法处理前向 ID 引用,我该如何解决这个问题?

4

2 回答 2

0

我尝试了另一种这次似乎可行的技巧。诀窍涉及以下内容:

  • 创建将 fooMap 转换为 TreeFooAdapter.MapType 的私有 getter/setter 对
  • 将 XmlID 添加到 TreeFooAdapter.MapType,并使用 XmlIDREF 注释 getter
  • 维护一组静态的 TreeFooAdapter.MapType 实例
  • 编组时,在编组 Tree 和 Foo 的所有实例之后,还要编组实例集。

这会产生更清晰的 XML:Trees 用简单的 IDREF 编组,用于它们的 fooMap,XML 文件的末尾只是一长串 TreeFooAdapter.MapTypes,它们本身就是成对的 IDREF 列表。如果您多次编组/解组,则必须小心清理静态实例集。

于 2012-08-31T14:09:52.513 回答
0

我发现了一个(可怕的、可怕的、丑陋的)解决方法,受此启发。我基本上概括了PhoneNumberAdapter 类来处理任何“可识别”,即具有唯一ID(即Foo 和Tree)。我没有一个 AdaptedPhoneNumber 类,而是有一个 ObjectWrapper bean,它要么包含被包装的实际对象(第一次遇到时),要么只包含它的 ID(在后续遇到时)。TreeFooAdapter 中的 MapEntry 类没有 XmlIDREF,而是将我的 IdentifiableAdapter 指定为 XmlJavaTypeAdapter。

这会创建可怕的、不可读的 XML,但至少它可以工作。尽管如此,这似乎是 JAXB 中的一个错误:经过一些痛苦的调试后,我仍然无法弄清楚为什么 XmlIDREF 在适应的 Map 类中不起作用。

于 2012-08-30T14:54:59.710 回答