Unmarshall MixedContent с Jaxb возвращает объекты с нулевыми переменными - PullRequest
0 голосов
/ 20 сентября 2019

Я хочу удалить XML-файл со смешанным содержимым.Я нашел поток в stackoverflow, который казался подходящим (использование JAXB- @XmlMixed для чтения @XmlValue и @ XmlElement ), где пользователь bdoughan определил 3 варианта использования для работы со смешанным содержимым.

Третий вариант использования будет хранить текст между тегами в одной строковой переменной и сохранять элементы в списке.Что я и хотел.К сожалению, я не мог заставить это работать, и нить довольно старая и возможно устаревшая.

Я пытался использовать вариант № 3 со списком объектов и списком моего справочного класса.Также я попробовал аннотации @XmlElement и @XmlValue.

Я использую javax.xml.bind jaxb-api в версии 2.3.1 и jaxb-runtime org.glassfish.jaxb в версии 2.3.1 в Maven Projec с Java SE версии 12.0.2.

Образец XML, который я тестировал с

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Date>
    2018.06.27
    <reference id="AnyId1">
    </reference>
</Date>

Представление моего класса

@XmlRootElement(name="Date")
public class TestPojo {

@XmlMixed
public String getTextContent() {
    return textContent;
}

public void setTextContent(String textContent) {
    this.textContent = textContent;
}

@XmlElementRef(name="reference", type = Reference.class)
public List<Object> getRef() {
    return ref;
}

public void setRef(List<Object> ref) {
    this.ref = ref;
}

String textContent;
List<Object> ref = new ArrayList<Object>();

}    

Я бы ожидал, что xml будет демаршалирован в объект POJO и правыйзначения назначены.Переменные Objects (textContent & ref) после отмены маршалирования становятся нулевыми.

1 Ответ

3 голосов
/ 22 сентября 2019

Вы можете попробовать это:

Используя базовый класс, как показано ниже,

@XmlAccessorType(XmlAccessType.FIELD)
public class Reference {
    @XmlAttribute
    private String id;
}

И ваш корневой класс,

@XmlRootElement(name="Date")
public class TestPojo {

    @XmlMixed
    @XmlAnyElement
    private List<Object> textContent;

    @XmlElement
    private Reference reference;

}

Это будет бесполезным, давая вамэлемент ссылки и все остальное в списке.

Для примера у вас будет 2 записи.Значение даты / текст вместе с символом табуляции (\ t) и символами новой строки (\ n), а также другая запись с символом новой строки.

Таким образом, вы можете использовать этот список для обработки содержимого и использовать то, что вы хотите.

Если есть более чистое решение, мне интересно.Приветствия

Обновление для ответа на комментарий:

Чтобы быть более понятным с исправлением.Я использовал @XmlElement вместо @XmlElementRef для одной ссылки вместо списка (потому что это то, что я видел в xml).

Также я добавил аннотацию @XmlAnyElement для смешанного контента, сделав его списком.Это то, что исправило это.Так что придерживайтесь своего класса, это будет выглядеть так:

@XmlRootElement(name="Date")
public class TestPojo {

    List<Object> textContent;
    Reference ref;

    @XmlMixed
    @XmlAnyElement
    public List<Object> getTextContent() {
        return textContent;
    }

    public void setTextContent(List<Object> textContent) {
        this.textContent = textContent;
    }

    @XmlElement(name="reference")
    public Reference getRef() {
        return ref;
    }

    public void setRef(Reference ref) {
        this.ref = ref;
    }

}

@XmlAccessorType сэкономил мне время на написание геттеров и сеттеров.Для объяснения того, что эта аннотация делает с примером (и относительно @XmlElement, проверьте это: В чем разница между использованием @XmlElement перед полем и перед объявлением получателя?

...