我有一个相当复杂的数据结构,我似乎无法正确地解组。
@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...
}
问题:转发参考不起作用!在解组时,无论哪个树首先出现在XML中,它的fooMap中都会有空键。由于这两棵树相互引用,我无法改变XML的顺序来解决这个问题。
我尝试过一个hack,其中我有一个私有方法来获取/设置List<TreeFooMapEntry>
,但它会产生相同的结果。
为什么JAXB在包含在Map或List中时无法处理转发ID引用,我该如何解决?
答案 0 :(得分:0)
我发现了一个(可怕的,可怕的,丑陋的)解决方法,受到this的启发。我基本上概括了PhoneNumberAdapter类以使用任何东西&#34; Identifiable&#34;,即具有唯一ID(即,Foo和Tree)。我没有一个AdaptedPhoneNumber类,而是有一个ObjectWrapper bean,它将包含被包装的实际对象(第一次遇到时),或者仅包含其ID(在后续遇到时)。 TreeFooAdapter中的MapEntry类,而不是XmlIDREF,而是将我的IdentifiableAdapter指定为XmlJavaTypeAdapter。
这会产生难以理解的,难以理解的XML,但至少它可行。尽管如此,这似乎是JAXB中的一个错误:经过一些痛苦的调试后,我仍然无法弄清楚为什么XmlIDREF在改编的Map类中不起作用。
答案 1 :(得分:0)
我尝试了另一个似乎有效的黑客攻击。诀窍涉及以下内容:
这会产生更清晰的XML:树用fooMaps为简单的IDREF编组,而XML文件的末尾只是一长串的TreeFooAdapter.MapTypes列表,它们本身就是IDREF对的列表。如果你多次封送/解组,你必须小心清理静态实例集。