java - JAXB 在 ChildA 继承中引用 ChildB
问题描述
我正在尝试解组以下 xml:
<?xml version="1.0" encoding="UTF-8" ?>
<container>
<childs>
<child uuid="1" childB="3" attrA="specialAttrA1" />
<child uuid="2" childB="4" attrA="specialAttrA2" />
<child uuid="3" attrB="specialAttrB1" />
<child uuid="4" attrB="specialAttrB2" />
</childs>
</container>
据我所知,这种情况包含两个主要问题:
- 对象层次建模
- 从另一个子类中引用一个子类
对象层次结构由 ChildA 和 ChildB 组成,它们是 Parent 的子类(参见下面的源代码)。
最后,除了引用“childB”为空之外,未编组的对象看起来不错。
我找不到这种情况的任何例子。调试下面的源问我为什么传递给适配器的 unmarshal-method 的 FlatParent 对象不包含 childB。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Container {
@XmlElementWrapper(name = "childs")
@XmlElement(name = "child")
private List<Parent> childs = new ArrayList<>();
}
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
@XmlJavaTypeAdapter(value = ParentAdapter.class, type = Parent.class)
public abstract class Parent {
@XmlID
@XmlAttribute
private String uuid;
}
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ChildA extends Parent{
@XmlAttribute
private String attrA;
@XmlIDREF
@XmlAttribute
private ChildB childB;
}
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class ChildB extends Parent{
@XmlAttribute
private String attrB;
}
对应的适配器如下所示:
public class ParentAdapter extends XmlAdapter<FlatParent, Parent> {
public Parent unmarshal(FlatParent fp) {
Parent p = null;
if (fp != null){
if (fp.getAttrA() != null){
p = new ChildA();
((ChildA) p).setAttrA(fp.getAttrA());
((ChildA) p).setChildB(fp.getChildB());
} else {
p = new ChildB();
((ChildB) p).setAttrB(fp.getAttrB());
}
p.setUuid(fp.getUuid());
}
return null;
}
...
}
以及包含的 FlatParent:
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class FlatParent {
@XmlID
@XmlAttribute
private String uuid;
@XmlAttribute
private String attrA;
@XmlAttribute
private String attrB;
@XmlIDREF
@XmlElement
private ChildB childB;
}
完全在这里也是测试类的一部分:
@Test
public void testImportXml() throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Container.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Container cont = (Container) unmarshaller.unmarshal(new File(FILEPATH));
解决方案
我认为你有两个选择:
1,使用unmarshaller-listener,缺点是您必须阅读 XML 两次并在每个涉及的对象解组后手动更新您的引用
2,按原样读取您的XML,使用数字并在使用java bean映射器解组到另一个pojos后将它们转换,例如MapStruct(在mapstruct中,具有相同名称的字段自动映射,您可以在装饰器子类中进行此引用映射)
推荐阅读
- python-3.x - 使用python定义类构造函数
- python - 如果 Join in pandas 中没有匹配项,则保留一列中的值
- javascript - JavaScript xml对象,访问节点问题
- javascript - CSS 星形单选按钮
- java - 如何使用 Java 在 Android Studio 中找到两条谷歌地图路线之间的交汇点
- python - 如何让 PyMongo collstats 匹配查询而不是整个集合
- java - 从另一个特定类访问 Class 方法
- r - 如何在表格中总结多个逻辑回归模型?
- php - 将对象数组传递给php
- configuration - 如何在 Visual Studio 中更改 NLog.config 文件位置