JAXB反序列化@XmlAnyElement

6
我创建了三个JAXB类:Home,Person,Animal。Java类Home有一个变量List<Object> any,可以包含Person和/或Animal实例。
    public class Home {
        @XmlAnyElement(lax = true)
        protected List<Object> any;
    //setter getter also implemented
    }
@XmlRootElement(name = "Person")                            // Edited
    public class Person {
        protected String name; //setter getter also implemented
     } 
@XmlRootElement(name = "Animal")                             // Edited
    public class Animal {
       protected String name; //setter getter also implemented
     }

/* 反序列化后 */

 Home home ;

                for(Object obj : home .getAny()){
                    if(obj instanceof Person ){
                        Person  person = (Person )obj;
                        // .........
                    }else if(obj instanceof Animal ){
                        Animal animal = (Animal )obj;
                        // .........
                    }
                }

我需要实现将 Person 或 Animal 对象保存在 "Home.any" List 变量中,但是 "Home.any" List 的内容是 com.sun.org.apache.xerces.internal.dom.ElementNSImpl 的实例,而不是 Animal 或 Person

那么有没有办法实现将以 xml 形式保存在 "Home.any" List 中的 Animal 或 Person 实例。

1个回答

8

如果您想要在使用@XmlAnyElement(lax=true)注解的字段/属性中显示某些类的实例,则需要在这些类上添加@XmlRootElement注解。

Java模型

主页

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Home {
    @XmlAnyElement(lax = true)
    protected List<Object> any;

    //setter getter also implemented
}

人员

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Person")
public class Person {

}

动物

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Animal")
public class Animal {

}

演示代码

input.xml

(输入文件)
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <Person/>
    <Animal/>
    <Person/>
</root>

演示

import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws JAXBException {
        JAXBContext jc = JAXBContext.newInstance(Home.class, Person.class, Animal.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StreamSource xml = new StreamSource("src/forum20329510/input.xml");
        Home home = unmarshaller.unmarshal(xml, Home.class).getValue();

        for(Object object : home.any) {
            System.out.println(object.getClass());
        }
    }

}

输出

class forum20329510.Person
class forum20329510.Animal
class forum20329510.Person

了解更多信息


我已经添加了@XmlRootElement(name = "Person")和@XmlRootElement(name = "Animal"),并在ObjectFactory.java中添加了条目。 - hiddenuser
@userG - 你是如何创建你的 JAXBContext 的?它是否知道你所有的类? - bdoughan
根据您的帖子,我认为;JAXBContext声明中存在问题:JAXBContext.newInstance(Home.class)。 - hiddenuser
我已经在ObjectFactory.java中定义了@XmlRootElement和entry。我只需要定义其中一个吗? - hiddenuser
感谢@Blaise的指导,我测试了您的代码,结果正如您所述。我正在开发NetBeans插件,并使用api org.netbeans.modules.xml.jaxb.api,但仍然遇到问题。为了暂时解决这个问题,我将dom.Element对象再次传递给unmarshall方法以检索jaxb对象。(我还看到JAXBContext.typeMap中存在Person和Animal两个引用。) - hiddenuser
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接