【问题标题】:JAXB - How to set the xsi:type of a XML element based on its value?JAXB - 如何根据其值设置 XML 元素的 xsi:type?
【发布时间】:2011-10-21 15:14:40
【问题描述】:

我必须生成一个 xml 元素,该元素的值可以是任何“原始类型”(xsd:string、xsd:boolean 等)。例子:

<field xsi:type="xsd:string" name="aString">String Value</field>
<field xsi:type="xsd:date" name="aDate">2011-10-21</field>
...

所以,我尝试了两种实现方式:

public class Field {
    @XmlAttribute
    private String name;

    @XmlValue
    Object value;
}

和...

public class Field<T> {
    @XmlAttribute
    private String name;

    @XmlValue
    T value;
}

我正在测试这个:

Marshaller marshaller = JAXBContext.newInstance(Field.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);

Field field = new Field();
field.name = "name";
field.value = "value";

ByteArrayOutputStream stream = new ByteArrayOutputStream();
marshaller.marshal(field, new PrintWriter(stream));
System.out.println(stream);

但是当我尝试实例化 JAXBContext 时,我得到了这个 NullPointerException

java.lang.NullPointerException
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:165)
at com.sun.xml.bind.v2.runtime.property.ValueProperty.<init>(ValueProperty.java:77)
at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:106)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:179)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:515)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:330)
at 

这个想法是允许字段元素的模式验证(它在模式中定义,必须在每个实例中设置其类型)。所以,即使这是一个错误(或不是)...... JAXB 如何将正确的xsi:type 放入该字段实例?我在这里遗漏了一个概念?

我知道问题可能出在 @XmlValue 的使用上,因为这个限制(来自 javadoc):

  • @XmlValue 注解最多可以对一个字段或属性进行注解。
  • @XmlValue 可以与以下注释一起使用:XmlList。然而,这是多余的,因为 XmlList 将一个类型映射到一个简单的模式类型,该类型由列表派生,就像 XmlValue 一样。
  • 如果字段或属性的类型是集合类型,则集合项类​​型必须映射到简单架构类型。
  • 如果字段或属性的类型不是集合类型,则该类型必须映射到 XML Schema 简单类型。

...因为Object 或通用T 不一定是XML Schema 简单类型,所以这种方法似乎不是正确的...

提前致谢...

【问题讨论】:

    标签: java xml xml-serialization jaxb


    【解决方案1】:

    我已确认您在 JAXB 的参考和 EclipseLink JAXB (MOXy) 实现中看到的问题。您看到的问题是由于使用了@XmlValue。如果value 属性被映射为@XmlElement,您将看到xsi:type 属性按预期显示。

    我已输入以下错误以在 EclipseLink JAXB (MOXy) 中跟踪此问题:

    根据您的域模型的外观,您可能对来自 EclipseLink JAXB (MOXy) 的 @XmlPath 扩展感兴趣:

    更新

    此问题现已在 EclipseLink 2.3.3 和 EclipseLink 2.4.0 中得到修复。从 2012 年 3 月 17 日开始,这些流中提供了该修复程序,并且可以从以下位置获得:

    【讨论】:

    • 感谢 Blaise 的回复...我会牢记您的选择(以及错误)。
    猜你喜欢
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多