根据以下程序,它会打印出我们正确的预期。 如果使用ClassA和ClassB类,这样的程序是否可以正确解组 相同的XmlRootElement名称?例如,如果它们都被定义为“typeA”......?可不可能是 可以用JAXB做那样的事情吗?
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.*;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Date;
public class JaxbABCTest {
public static void main(String[] args) throws JAXBException, UnsupportedEncodingException {
final JAXBContext context = JAXBContext.newInstance(ABC.class);
final Marshaller marshaller = context.createMarshaller();
final Unmarshaller unmarshaller = context.createUnmarshaller();
ABC class1 = new ClassA();
ABC class2 = new ClassB();
final ByteArrayOutputStream baosA = new ByteArrayOutputStream();
final ByteArrayOutputStream baosB = new ByteArrayOutputStream();
// Marshall to XML
marshaller.marshal(class1, baosA);
marshaller.marshal(class2, baosB);
String xmlA = baosA.toString(Charset.defaultCharset().name());
String xmlB = baosB.toString(Charset.defaultCharset().name());
System.out.println(xmlA);
System.out.println(xmlB);
// Now attempt the reverse.
Object unmarshalA = unmarshaller.unmarshal(new StringReader(xmlA));
Object unmarshalB = unmarshaller.unmarshal(new StringReader(xmlB));
System.out.println(unmarshalA.getClass());
System.out.println(unmarshalB.getClass());
}
}
@XmlTransient
@XmlSeeAlso({
ClassA.class,
ClassB.class
})
abstract class ABC {
private int a;
@XmlAttribute
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
@XmlRootElement(name = "typeA")
class ClassA extends ABC {
private String b;
private Date c;
@XmlAttribute
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
@XmlAttribute
public Date getC() {
return c;
}
public void setC(Date c) {
this.c = c;
}
}
@XmlRootElement(name = "typeB")
class ClassB extends ABC {
private String b;
private Date c;
private boolean d;
private float e;
@XmlAttribute
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
@XmlAttribute
public Date getC() {
return c;
}
public void setC(Date c) {
this.c = c;
}
@XmlAttribute
public boolean isD() {
return d;
}
public void setD(boolean d) {
this.d = d;
}
@XmlAttribute
public float getE() {
return e;
}
public void setE(float e) {
this.e = e;
}
}
答案 0 :(得分:1)
对于简单的JAXB解组,(root)一个元素名称是指具有特定结构的元素,该结构映射到某个Java类。
当然,您可以定义一个包含A和B字段并集的类 - 只要两个类中出现的字段匹配即可。你必须有一些属性,让你决定它真正是两个“子类”中的哪一个。 (这与使用包含对属性或元素的存在(或甚至值)的测试的XPath表达式的精神相似。)
您也可以采用更精细的方法,在阅读XML之后将此元素解组,调查DOM树并根据检测到的内容创建JAXBContext。这将允许您使用与XML类型完全匹配的Java类型相同的元素名称。当然,必须有一个明确的标准,你必须编写基于原始DOM树数据进行分析的代码。