用来记录一些原创性的总结
在上一篇文章中介绍了使用@XmlAnyElement处理匹配任意XML元素转换为对象的场景,本文将介绍使用XmlAnyElement将对象转换为XML。
考虑如下这样的代码场景,我们有一个AnyObjHolder类,其拥有一个objs类型的属性,该属性中可以存放任意类型的元素。为了简单一点,我们假设它可以存放的类型只会有AnyObj1、AnyObj2或者AnyObj3。那么它生成的XML会是什么样呢?
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="holder")
class AnyObjHolder {
private List<Object> objs;
public List<Object> getObjs() {
return objs;
}
public void setObjs(List<Object> objs) {
this.objs = objs;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class AnyObj1 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class AnyObj2 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class AnyObj3 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
正常情况下它生成的XML会是如下这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<holder>
<objs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="anyObj1">
<abc>123</abc>
</objs>
<objs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="anyObj2">
<abc>123</abc>
</objs>
<objs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="anyObj3">
<abc>123</abc>
</objs>
</holder>
如果我们期望AnyObj1类型的对象生成的XML的根节点是obj1,AnyObj2类型的对象生成的XML的根节点是obj2,AnyObj3类型的对象生成的XML的根节点是obj3。这个时候我们就可以把objs使用@XmlAnyElement修饰,在AnyObj1类上通过@XmlRootElement(name=”obj1”)指定生成的节点的名称为obj1,在AnyObj2类上通过@XmlRootElement(name=”obj2”)指定生成的节点的名称为obj2,在AnyObj3类上通过@XmlRootElement(name=”obj3”)指定生成的节点的名称为obj3。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="holder")
class AnyObjHolder {
@XmlAnyElement
private List<Object> objs;
public List<Object> getObjs() {
return objs;
}
public void setObjs(List<Object> objs) {
this.objs = objs;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="obj1")
class AnyObj1 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="obj2")
class AnyObj2 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="obj3")
class AnyObj3 {
private String abc;
public String getAbc() {
return abc;
}
public void setAbc(String abc) {
this.abc = abc;
}
}
这样生成的XML会是如下这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<holder>
<obj1>
<abc>123</abc>
</obj1>
<obj2>
<abc>123</abc>
</obj2>
<obj3>
<abc>123</abc>
</obj3>
</holder>
看到这里,可能你会想这跟我们之前介绍的@XmlElementRef有类似的效果。乍一看是类似的,实际上@XmlElementRef是用于父类和子类的关系,且List<Object> objs
这里指定的泛型需要是对应的父类型,且不能是Object
类型,这就是它们之间的差别。
(本文由Elim写于2017年9月11日)