2015-02-01 4 views
1

Я новичок в простой инфраструктуре для XML (Java) и столкнулся с проблемой сериализации конкретных конструкций класса.Ссылка на поле по его идентификатору вместо его расширения

У меня есть два класса:

@Root(name="static") 
class StaticData { 
    @Attribute 
    private String id; 
    @Attribute 
    private String value; 
... 
} 

и

@Root(name="listdata") 
class ListData { 
    // Problem field 
    @Attribute 
    private StaticData ref; 
    @Element 
    private String name; 
} 

И получают "TransformException: преобразование класса StaticData не поддерживается". Я хочу, чтобы поле ref в ListData не расширялось в структуру XML статических данных (тогда @Element было бы хорошо), но чтобы получить ссылку.

<listdata ref="foo"> 
    <name>bla bla</name> 
</listdata> 

где «foo» является допустимым значением для «id» в некотором объекте StaticData, уже загруженном в мое приложение.

В JAXB Я хотел бы использовать XmlJavaTypeAdapter аннотацию

@XmlAttribute(name="id") 
@XmlJavaTypeAdapter(MyStaticDataAdapter.class) 

, но я не могу найти рабочий эквивалент в Simple.

ответ

0

Уверенный воблер Вы можете использовать преобразователь для реализации такого поведения.

Вот пример:

@Root(name = "listdata") 
@Convert(ListData.ListDataConverter.class) 
class ListData 
{ 
    @Attribute 
    private StaticData ref; 
    @Element 
    private String name; 

    // ... 

    // Converter implementation 
    static class ListDataConverter implements Converter<ListData> 
    { 

     @Override 
     public ListData read(InputNode node) throws Exception 
     { 
      /* 
      * In case you also want to read, implement this too ... 
      */ 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     @Override 
     public void write(OutputNode node, ListData value) throws Exception 
     { 
      node.setAttribute("ref", value.ref.getId()); 
      node.getChild("name").setValue(value.name); 
     } 
    } 
} 

Использование:

Serializer ser = new Persister(new AnnotationStrategy()); 
          /* ^----- important! -----^ */ 

ListData ld = ... 
ser.write(ld, System.out); // Serialize to std out 

Выход

С этими ListData значениями ...

  • имя = АБВГДЕЖ
  • исх = ...
    • ID = 123
    • значение = это значение,

вы получите ...

<listdata ref="123"> 
    <name>def</name> 
</listdata> 
+0

спасибо. Это именно то, что я искал. Я уже пробовал с моим собственным конвертером, но я попытался реализовать его для StaticData вместо ListData - что не удалось. – taranion

+0

Один недостаток. Существует два варианта использования конвертера в ListData - глобально для всего класса или только для одного поля. Если применяется ко всему классу, я должен позаботиться о * ALL * других полях, которые обычно дают хорошие результаты. Кажется, что поведение по умолчанию не работает. Если я использую его для одного поля, я все равно получаю ту же ошибку. – taranion

+0

Если вы используете конвертер для поля, вам нужно применить к нему '@ Element'. Например. '@Element @Convert (WhatEver.класс) '. Но я не уверен, что тогда вы можете получить доступ к родительскому узлу Xml. – ollo

Смежные вопросы