Как установить xsi: тип элемента XML на основе его значения? - PullRequest
4 голосов
/ 21 октября 2011

Мне нужно сгенерировать элемент 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);

Но я получаю это NullPointerException, когда пытаюсь создать экземпляр JAXBContext.

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.

... поскольку Object или универсальный T не обязательно являются простым типом XML-схемы, этот подход кажется не правильным ...

Заранее спасибо ...

1 Ответ

2 голосов
/ 21 октября 2011

Я подтвердил проблему, которую вы видите как в справочной информации, так и в EclipseLink JAXB (MOXy) реализации JAXB.Проблема, которую вы видите, связана с использованием @XmlValue.Если бы свойство value было отображено как @XmlElement, вы бы увидели, что атрибут xsi:type выглядит как положено.

Я ввел следующую ошибку, чтобы отследить эту проблему в EclipseLink JAXB (MOXy):

В зависимости от того, как выглядит модель вашего домена, вас может заинтересовать расширение @XmlPath от EclipseLink JAXB (MOXy):

ОБНОВЛЕНИЕ

Эта проблема была теперь исправлена ​​в EclipseLink 2.3.3 и EclipseLink 2.4.0.Исправление доступно в этих потоках, начиная с 17 марта 2012 года, и его можно получить по адресу:

...