根据以下程序,它会正确打印出我们期望的内容。 如果使用 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;
}
}
最佳答案
对于简单的 JAXB 解码,(根)一个元素名称是指具有映射到某个 Java 类的特定结构的元素。
当然,您可以定义一个包含 A 和 B 字段并集的类 - 只要两个类中出现的字段匹配即可。你必须有一些属性来让你决定它到底是两个“子类”中的哪一个。 (这在本质上类似于使用 XPath 表达式,其中包括对属性或元素是否存在(甚至值)的测试。)
您还可以采用更复杂的方法,在读取 XML 后保留此元素,调查 DOM 树并根据检测到的内容创建 JAXBContext。这将允许您使用与 XML 内容完全匹配的 Java 类型的相同元素名称。当然,必须有一个明确的标准,并且您必须编写基于原始 DOM 树数据进行分析的代码。
关于java - JAXB 解码派生类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27395788/