Демаршалинг xml, где атрибуты определяют тип

Мне дают документы XML (которые я не могу контролировать его формат). Я хотел бы знать, возможно ли демаршалировать этот xml на основе идентификатора атрибута элемента. Таким образом, разные типы объектов будут иметь одинаковое имя элемента.

Кроме того, я планирую использовать Simpile XML, потому что я на Android, а JAXB не любит Android.

Поэтому я хотел бы что-то вроде:

class Root {
  Person p;
  Car c;
  ArrayList<Person> plist;
}

class Person{
  String name;
}

class Car {
  String type;
}

от

<root>
  <object id="person">
    <name> bob </name>
  </object>
  <object id="car">
    <model> ford </ford>
  </object>
  <sequence id="personSequence">
    <object id="person">
      <name> bob </name>
    </object>
    <object id="person">
      <name> bob </name>
    </object>
  </sequence>
</root>

Однако я точно знаю, что документ, который я получаю, всегда будет в одном и том же порядке с одинаковым количеством элементов верхнего уровня. Например,

У Rool всегда будет: 1 человек, 1 машина, 1 человек, 2 машины и последовательность автомобилей неизвестного размера.

<root>
  <person />
  <car />
  <person />
  <car />
  <car />
  <sequence >
    I don't know how many objects will be in here
  <sequence >
<root>

Спасибо.

1 ответ

Вы можете использовать Converter Выполнение этого. Это позволяет вам реализовать процесс (де) сериализации самостоятельно.

Вот предложение, как это сделать:

  • Абстрактный класс как база для всех объектов (людей, автомобилей и т. Д.)
  • Реализации для тех
  • Корневой объект, содержащий все остальные элементы
  • Converter который создает конкретный корень-объект из узлов

Btw. вам не нужно добавлять эти простые аннотации, если вы используете конвертеры - однако, это всегда хорошая идея, на тот случай, если они вам нужны.

(Аннотация) Базовый класс для всех объектов:

@Root()
public abstract class ObjectElement
{
    @Attribute(name = "id")
    private String id;


    public ObjectElement(String id)
    {
        this.id = id;
    }

    // ...
}

Персональный класс:

@Root(name = "object")
public class PersonObject extends ObjectElement
{
    @Element(name = "name")
    private String name;


    public PersonObject(String name)
    {
        super("person");
        this.name = name;
    }

    // ...
}

Класс автомобиля:

@Root(name = "object")
public class CarObject extends ObjectElement
{
    @Element(name = "model")
    private String model;


    public CarObject( String model)
    {
        super("car");
        this.model = model;
    }

    // ...
}

Класс последовательности:

@Root(name = "sequence")
public class SequenceObject extends ObjectElement
{
    @ElementList(inline = true)
    private final List<ObjectElement> elements;


    public SequenceObject()
    {
        super("personSequence");
        this.elements = new ArrayList<>();
    }

    // ...
}

root -элемент; у него есть экземпляры его детей (автомобили и т. д.) и карты <root> ... </root> элемент.

@Root(name = "root")
@Convert(RootElementConverter.class) // Set Converter here!
public class RootElement
{
    private final List<ObjectElement> elememts;


    public RootElement()
    {
        this.elememts = new ArrayList<>();
    }


    public void add(ObjectElement element)
    {
        this.elememts.add(element);
    }

    // ...
}

Converter:

public class RootElementConverter implements Converter<RootElement>
{
    @Override
    public RootElement read(InputNode node) throws Exception
    {
        RootElement root = new RootElement();

        /*
         * Iterate over all nodes and add them to root. You can use 
         * "node.getName()" and "node.getAttribute(...)" to test what
         * instance you have to add.
         * 
         * Use "root.add(...)" to add nodes.
         */

        return root;
    }


    @Override
    public void write(OutputNode node, RootElement value) throws Exception
    {
        /*
         * Implement this if you also serialize to xml.
         */
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

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

final String xml = ...

// Important: Don't forget the AnnotationStrategy!
Serializer ser = new Persister(new AnnotationStrategy());

// Read root-object from xml-string or whatever
RootElement root = ser.read(RootElement.class, xml);
Другие вопросы по тегам