【发布时间】: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