我正在使用XStream加载如下结构的文件:
<parent>
<child/>
<child/>
</parent>
进入这样一个类:
public class Parent(){
private List<Child> children;
}
public class Child {
private Parent parent;
}
我希望能够这样做:parent.getChildren().get(0).getParent()
我希望能够使用XML。我知道我可以在子项下添加对父项的引用,但这似乎非常多余。由于XML结构,我知道childs parent。
XStream是否支持此功能?
答案 0 :(得分:3)
是Xstream支持反向链接以避免循环引用。它默认情况下会这样做,但是它是否可以证明需要它的消息是否真的合适。它可以通过网络释放一些数据,但实际上不是一个“消息”,更像是一个序列化的对象。
您的子对象需要有一个指向父对象的指针。
答案 1 :(得分:2)
一种选择是在父级中使用readResolve
来设置反向引用。根据此处的XStream FAQ,将以与标准库序列化相同的方式调用此方法:http://x-stream.github.io/faq.html#Serialization_initialize_transient
调用readResolve
时,Parent
及其所有子项已经被反序列化,因此您可以在此时设置反向引用。
public class Parent {
private List<Child> children = new ArrayList<Child>();
private Object readResolve() {
for( Child child: children ) {
child.setParent(this);
}
return this;
}
}
答案 2 :(得分:0)
如果您愿意考虑使用XStream之外的其他内容,那么EclipseLink JAXB (MOXy)可以使用@XmlInverseReference轻松处理双向属性(我是MOXy技术主管)。
您的对象模型将映射为:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Parent {
private List<Child> children;
@XmlElement(name="child")
public List<Child> getChildren() {
return children;
}
public void setChildren(List<Child> children) {
this.children = children;
}
}
和(注意在父属性上使用@XmlInverseReference):
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
public class Child {
private Parent parent;
@XmlInverseReference(mappedBy="children")
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
演示代码看起来像(input.xml引用了你问题中的XML):
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Parent.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Parent parent = (Parent) unmarshaller.unmarshal(new File("input.xml"));
for(Child child : parent.getChildren()) {
System.out.println(child.getParent());
}
}
}
要将MOXy指定为JAXB实现,您需要在与模型类相同的包中包含一个名为jaxb.properties的文件,并带有以下条目:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
下面是我对JAXB和XStream的比较的链接: