JAXB命名空间问题与扩展注释类的成员
我有3个带批注的类(我谨慎地删除了getters,setters等,以使代码更具可读性):
Result.java
@XmlRootElement(name = "resultat")
@XmlType(propOrder = { "state", "content" })
public class Result {
protected State state;
protected Content content;
}
Content.java:
@XmlRootElement(name = "content")
@XmlSeeAlso({ Job.class })
public class Content {
}
和扩展内容的Job.java:
@XmlType(name = "job", propOrder = { "status" })
@XmlRootElement(name = "job")
public class JobStatus extends Content {
protected String status;
}
我将Job实例设置为结果类的内容成员的值,但是我得到以下生成的xml文件:
<result>
<state>
<tag>value</tag>
</state>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="job">
<status>ok</status>
</content>
</result>
但它不是一个有效的xml文件,并且由于“xmlns:xsi =”http://www.w3.org/2001/XMLSchema-instance“xsi:type =”job“,因此无法根据以下架构进行验证。 “部分,因为工作不是来自http://www.w3.org/2001/XMLSchema-instance的类型。
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="result">
<xs:complexType>
<xs:sequence>
<xs:element name="state">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="tag"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="status"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
如何更改我的JAXB配置以避免此问题?
谢谢 !
问题不在于JAXB配置,而在于架构与Java类的设计。
Java类Content
不符合您的Schema,因为元素status
在Schema中定义,但不在Java Class中定义。 另外,您不需要在Schema中定义job
。
属性xsi:type
用于继承。 由于您的JobStatus类继承自内容,因此它以XML的形式显示为job
类型的content
。
我认为最好的解决方案是从架构中的content
中删除元素status
,然后在架构中定义job
,如下所示:
<complexType name="job">
<complexContent>
<extension base="content">
<sequence>
<xs:element type="xs:string" name="status"/>
</sequence>
</extension>
</complexContent>
</complexType>
WA是正确的,您的JAXB实现完全按照您的要求进行(请参阅:http://blog.bdoughan.com/2010/11/jaxb-and-inheritance-using-xsitype.html)。 如果你不想改变你的XML模式,下面是你可以如何改变你的映射。
Java模型
结果
我们将在content
字段上使用@XmlElement
注释来指示实际类型是Job
(请参阅:http://blog.bdoughan.com/2011/05/jaxb-and-interface-fronted-models.html)。
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(propOrder = { "state", "content" })
@XmlAccessorType(XmlAccessType.FIELD)
public class Result {
protected State state;
@XmlElement(type=Job.class)
protected Content content;
}
内容
我们将在Content
类中使用@XmlTransient
注释将其从继承层次结构中移除(请参阅:http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html)。
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
public class Content {
}
工作
Job
正常映射。
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Job extends Content {
protected String status;
}
演示代码
演示
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Result.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum17993543/input.xml");
Result result = (Result) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(result,System.out);
}
}
input.xml中/输出
<?xml version="1.0" encoding="UTF-8"?>
<result>
<state>
<tag>value</tag>
</state>
<content>
<status>ok</status>
</content>
</result>
链接地址: http://www.djcxy.com/p/51715.html
上一篇: JAXB namespace issue with extended annotated class' member