EclipseLink MOXy为使用@XmlElement注释的Object类型的字段存储DOM Element的实例

时间:2014-06-20 12:14:19

标签: java jaxb eclipselink moxy

我们在项目中使用MOXy JAXB。

模特课程:

@XmlRootElement(name = "field")
@XmlType(propOrder = {"id","value"})
public class FieldData{
    @XmlAttribute
    private String id;
    @XmlAttribute
    private Object value;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public Object getValue() {
        return value;
    }
    public void setValue(Object value) {
        this.value = value;
    }
}

对于我的用例,我希望value是Object本身的类型,因为我可以在这里获得任何原始数据类型值。我最初将它们作为字符串。获得对象后,我进行类型转换并将其保存到同一个字段中。上述用例工作正常。但是,当我将@XmlAttribute更改为@XmlElement时,它无法正常工作。我看到该值是作为ElementNSImpl的一个实例解组的。有没有解决这个问题?

1 个答案:

答案 0 :(得分:1)

以下是您所看到的大脑转储:


演示代码

我将使用与下面描述的不同映射相同的演示代码:

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Foo.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Foo foo = (Foo) unmarshaller.unmarshal(xml);

        System.out.println(foo.getBar().getClass());
    }

}

用例#1 - 使用@XmlAttribute

映射的对象属性

Java模型

<强>富

我们使用@XmlAttribute注释将属性映射到@XmlAttribute注意:使用JAXB参考实现时,这不是有效的配置。

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Foo {

    private Object bar;

    @XmlAttribute
    public Object getBar() {
        return bar;
    }

    public void setBar(Object bar) {
        this.bar = bar;
    }

}

XML#1

<强> input.xml中

在下面的XML文档中,bar属性包含数字。

<?xml version="1.0" encoding="UTF-8"?>
<foo bar="123"/>

<强>输出

由于没有输入信息(在XML或Java类中),MOXy将值作为StringString是最具体的类型,可以表示XML属性上的所有可能值。

class java.lang.String

XML#2

<强> input.xml中

在下面的XML文档中,bar属性包含字母字符。

<?xml version="1.0" encoding="UTF-8"?>
<foo bar="Hello World"/>

<强>输出

String是最具体的类型,可以表示XML属性上的所有可能值。

class java.lang.String

使用案例#2使用@XmlElement

映射的对象属性

Java模型

<强>富

Foo类的此版本中,我们不会注释bar属性,这与使用@XmlElement注释它相同。

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Foo {

    private Object bar;

    public Object getBar() {
        return bar;
    }

    public void setBar(Object bar) {
        this.bar = bar;
    }

}

XML#1(简单元素)

<强> input.xml中

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar>Hello World</bar>
</foo>

<强>输出

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl

XML#2(复杂元素)

<强> input.xml中

现在bar元素不包含仅测试,而是包含XML属性和子元素。

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar a="1">
       <b>2</b>
       <c>3</c>
    </bar>
</foo>

<强>输出

现在我们开始明白为什么JAXB将值视为DOM,元素可能是任意复杂的,因此DOM元素成为可以保存任何可能值的结构。

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl

XML#3(类型化元素)

<强> input.xml中

在下面的XML文档中

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <bar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">Hello World</bar>
</foo>

<强>输出

class java.lang.String

使用案例#3使用@XmlElement(type=String)

映射的对象属性

Java模型

<强>富

Foo类的这个版本中,我们将使用bar Object @XmlElement(type=String.class). As far as Java is concerned the property is still of type String`注释, but JAXB will treat the property as if it's type属性。

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Foo {

    private Object bar;

    @XmlElement(type=String)
    public Object getBar() {
        return bar;
    }

    public void setBar(Object bar) {
        this.bar = bar;
    }

}

XML#1(简单元素)

现在我们看到bar元素的值被视为String

<强> input.xml中

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar>Hello World</bar>
</foo>

<强>输出

class java.lang.String