Десериализовать внутреннюю часть XML в новый экземпляр класса

Дан XML в следующем (упрощенном) формате:

<outer><inner><field1>a</field1><field2>b</field2><field3>c</field3></inner></outer>

Я хотел бы десериализовать элемент <inner> в класс, представляющий его, и отбросить остальные.

public class Inner {
    private String field1;
    private String field2;
    private String field3;
    // getters, setters, ctor
}

Я использую класс Jackson XmlMapper для выполнения десериализации. Если я уберу <outer> из строки xml, очевидно, это сработает.

XmlMapper xmlMapper = new XmlMapper();
// in my scenario the `<inner>` element actually contains fields I don't care about
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Inner inner = xmlMapper.readValue(xml, Inner.class);
System.out.println(inner);
// Inner(field1=a, field2=b, field3=c)

Если я оставлю элемент <outer>, все поля в inner будут нулевыми.

Я попытался аннотировать класс Inner с помощью @JacksonXmlRootElement(localName = "inner"), но это не изменило результат.

Я мог бы создать класс, представляющий элемент <outer>, но это кажется расточительным. Вероятно, я мог бы также создать новую строку, содержащую только xml между элементами <inner>, но опять же, это выглядит немного хакерским.

В моем случае xml передается отдельной системой, которую я не могу контролировать, поэтому я могу просто изменить структуру xml.

Можно ли десериализовать «внутренний» xml в новый экземпляр класса?


person Daniel Kelley    schedule 04.05.2017    source источник


Ответы (1)


Похоже, что для того, чтобы @JacksonXmlRootElement(localName = "inner") работало так, как вы ожидаете, вам также необходимо UNWRAP_ROOT_VALUE. Например.

xmlMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

Я не могу сказать, что вышеизложенное очень очевидно из документов.

person Manos Nikolaidis    schedule 05.05.2017
comment
Спасибо. Кажется, эта особенность была ключевой. - person Daniel Kelley; 05.05.2017