Unmarshall Вложенный XML с JAXB - PullRequest
0 голосов
/ 08 ноября 2018

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

Структура XML:

<CURRENT_VALUES>
    <agency>
        <value xsi:type="xs:long" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">123</value>
    </agency>
    <company>
        <value xsi:type="xs:long" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">1</value>
    </company>
    <channel>
        <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TEST</value>
    </channel>
</CURRENT_VALUES>

Я создал POJO так:

public class EventoModel 
{
    private String agency;
    private String company;
    private String channel;

    public String getAgency() {
        return agency;
    }

    public void setAgency(String agency) {
        this.agency = agency;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }
}

Проблема в элементе value.
Когда я пытаюсь отменять маршалинг, свойства POJO пусты (или ноль).

JAXBContext jaxbContext = JAXBContext.newInstance(EventoModel.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
XMLOutputter outputter = new XMLOutputter();
StringReader reader = new StringReader(outputter.outputString(xml));
EventoModel evento = (EventoModel) unmarshaller.unmarshal(reader);

1 Ответ

0 голосов
/ 09 ноября 2018

Элементы XML <agency>, <company> и <channel> имеют довольно сложную структуру вложенности. Поэтому слишком просто моделировать их как свойства Java String.

Вместо этого вам нужен отдельный класс POJO для них. Поскольку 3 имеют одинаковую структуру, мы можем использовать общий класс для всех них. Не имея лучшего названия, назовем этот класс Ìtem. Обратите внимание, что все 3 свойства помечены @XmlElement.

@XmlRootElement(name = "CURRENT_VALUES")
@XmlAccessorType(XmlAccessType.FIELD)
public class EventoModel 
{
    @XmlElement
    private Item agency;

    @XmlElement
    private Item company;

    @XmlElement
    private Item channel;

    // public getters and setters (omitted here for brevity)
}

Класс Item может выглядеть следующим образом. Он содержит свойство с именем value, моделирующее элемент XML <value>. Обратите внимание, свойство помечается @XmlElement

@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

    @XmlElement
    private Value value;

    // public getters and setters (omitted here for brevity)
}

Элемент XML <value> все еще довольно сложен. Поэтому нам нужен еще один класс POJO для его моделирования. Давайте назовем класс Value.

Текст XML между <value ...> и </value> моделируется свойством String text, который должен быть аннотирован @XmlValue.

Атрибут XML xsi:type="..." моделируется свойством String type, который должен быть аннотирован @XmlAttribute. Обратите особое внимание на параметр namespace, который соответствует пространству имен XML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance".

@XmlAccessorType(XmlAccessType.FIELD)
public class Value {

    @XmlAttribute(namespace = "http://www.w3.org/2001/XMLSchema-instance")
    private String type;

    @XmlValue
    private String text;

    // public getters and setters (omitted here for brevity)
}

Снимок экрана ниже (взятый из отладчика) визуализирует все Java структура и подтверждает, что unmarshalling работает правильно:

screenshot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...