JAXB 解组@XmlAnyElement

Posted

技术标签:

【中文标题】JAXB 解组@XmlAnyElement【英文标题】:JAXB Unmarshalling @XmlAnyElement 【发布时间】:2013-12-18 05:35:09 【问题描述】:

我创建了三个 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;
                        // .........
                    
                

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

那么有没有办法实现Animal or Person实例保存在"Home.any" List中的xml中。

【问题讨论】:

【参考方案1】:

您需要将@XmlRootElement 添加到您希望作为实例出现在您已使用@XmlAnyElement(lax=true) 注释的字段/属性中的类上。

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

更多信息

http://blog.bdoughan.com/2012/12/jaxbs-xmlanyelementlaxtrue-explained.html

【讨论】:

我已经添加了 @XmlRootElement(name = "Person") 和 @XmlRootElement(name = "Animal") 在 ObjectFactory.java 中也添加了条目。 @userG - 你是如何创建你的JAXBContext 的,它知道你所有的类吗? 根据您的帖子,我认为; JAXBContext 声明 JAXBContext.newInstance(Home.class) 存在问题。 我已经在 ObjectFactory.java 中定义了 @XmlRootElement 和 entry 。我必须只定义其中一个吗? JAXBContext.newInstance(Home.class,Person.class,Animal.class) , @XmlRootElement 已经添加并且来自 ObjectFactory.java 的条目已注释但仍未解决。

以上是关于JAXB 解组@XmlAnyElement的主要内容,如果未能解决你的问题,请参考以下文章

JAXB 解组@XmlAnyElement

解组 JAXB 编组列表失败并出现 NullPointerException

解组非根元素时的 JAXB 模式验证

使用 DTD 文件导致的 JAXB 解组 XML 时出错

JAXB 解组集合

Java/JAXB:根据属性将 Xml 解组为特定子类