Xml 带有扩展注释类的JAXB命名空间问题';成员

Xml 带有扩展注释类的JAXB命名空间问题';成员,xml,jaxb,xsd,xml-namespaces,jaxb2,Xml,Jaxb,Xsd,Xml Namespaces,Jaxb2,我有3个带注释的类(我慎重地删除了getter、setter等,以使代码更具可读性): Result.java @XmlRootElement(name = "resultat") @XmlType(propOrder = { "state", "content" }) public class Result { protected State state; protected Content content; } Content.java: @XmlRootElement(n

我有3个带注释的类(我慎重地删除了getter、setter等,以使代码更具可读性):

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;
}
我正在将作业实例设置为结果类的内容成员的值,但我得到以下生成的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”部件,因为作业不是来自的类型


如何更改JAXB配置以避免此问题


谢谢

问题不在于JAXB配置,而在于模式与Java类的设计

Java类
内容
不符合您的模式,因为元素
状态
是在模式中定义的,而不是在Java类中定义的。 此外,您没有在模式中定义
作业

属性
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>

您的JAXB实现完全按照您的指示执行(请参阅:)。如果您不想更改XML模式,下面是如何更改映射

Java模型 结果

<?xml version="1.0" encoding="UTF-8"?>
<result>
    <state>
        <tag>value</tag>
    </state>
    <content>
        <status>ok</status>
    </content>
</result>
我们将在
content
字段上使用
@xmlement
注释来指示实际类型是
Job
(请参阅:)

import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(propOrder={“状态”,“内容”})
@XmlAccessorType(XmlAccessType.FIELD)
公开课成绩{
受保护国家;
@XmlElement(类型=Job.class)
受保护的内容;
}
内容

<?xml version="1.0" encoding="UTF-8"?>
<result>
    <state>
        <tag>value</tag>
    </state>
    <content>
        <status>ok</status>
    </content>
</result>
我们将在
Content
类上使用
@xmltransive
注释将其从继承层次结构中删除(请参见:)

import javax.xml.bind.annotation.xmltransive;
@XmlTransient
公开课内容{
}
工作

作业
映射正常

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Job extends Content {
    protected String status;
}
演示代码 演示

导入java.io.File;
导入javax.xml.bind.*;
公开课演示{
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(Result.class);
Unmarshaller Unmarshaller=jc.createUnmarshaller();
File xml=新文件(“src/forum17993543/input.xml”);
结果=(Result)unmarshaller.unmarshal(xml);
Marshaller=jc.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
marshaller.marshall(结果、系统、输出);
}
}
input.xml/Output

<?xml version="1.0" encoding="UTF-8"?>
<result>
    <state>
        <tag>value</tag>
    </state>
    <content>
        <status>ok</status>
    </content>
</result>

价值
好啊

+1-仅供参考-以下是如何更改JAXB映射以支持此用例:实际上许多类扩展了内容,Job只是其中之一。因此,结果是一个标准响应,可能会嵌入不同的内容。我无法使您的解决方案与扩展内容的不同类一起工作,这可能吗?