Джексон XmlMapper сопоставляет XML-атрибут вложенного элемента

Я пытаюсь разобрать XML в класс Java, а затем отправить его во внешний интерфейс. Я использую Springboot 2.2.5, формат данных Джексона xml 2.10.2

У меня есть следующий файл XML:

<root xmlsn="...">
  <result status="1" outs="6" val="0" pic="7"/>
</root>

Я ожидаю этого ответа от бэкэнда на внешнем интерфейсе:

{
  status: 1,
  outs: 6,
  val: 0
  pic: 7
}

Ну, это очень просто.

Посмотрим, что у меня есть:

Класс для корневого элемента:

@JacksonXmlRootElement(namespace = "...", localName = "root")
public class SetXmlResponseDto {

    @JacksonXmlProperty(localName = "result")
    private ResultPropertyDto result;
}

А затем класс для элемента результата ResultPropertyDto:

public class ResultPropertyDto {

    @JacksonXmlProperty(localName = "val", isAttribute = true)
    private String value;

    @JacksonXmlProperty(localName = "status", isAttribute = true)
    private String status;
}

// Я удалил некоторые части кода для brewity (сеттер, геттер)

Но результат этого следующий:

{
  result: {
    status: 1,
    ....
  }
}

Вероятно, неплохо также упомянуть, как я его строю?

ObjectMapper objectMapper = new XmlMapper();
objectMapper().readValue(new URL(urlAddress), SetXmlResponseDto.class);

Конечно, я мог бы просто вызвать SetXmlResponseDto.getStatus() перед отправкой во внешний интерфейс, и вывод будет точно таким, как ожидалось, но мне было интересно, есть ли способ добиться требуемого результата без создания подкласса ResultPropertyDto ??

Представьте, что у вас есть 4 вложенных элемента в XML, и вы хотите отобразить только 1 атрибут этого вложенного элемента. Я должен был бы создать 4 класса для этого??

Спасибо за ответы


person Kuba Šimonovský    schedule 17.04.2020    source источник


Ответы (1)


Если вы хотите избежать создания глубоко вложенных структур, вы всегда можете использовать xpath.

Из упомянутой ссылки на документацию:

рассмотрите следующий файл widget.xml

<widgets>
  <widget>
     <manufacturer/>
     <dimensions/>
  </widget>

The element can be selected with the following XPath API code:

// parse the XML as a W3C Document
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new File("/widgets.xml"));

XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/widgets/widget";
Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);

Со ссылкой на элемент теперь можно записать относительное выражение XPath для выбора дочернего элемента:

XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "manufacturer";
Node manufacturerNode = (Node) xpath.evaluate(expression, widgetNode, XPathConstants.NODE);
person Eirini Graonidou    schedule 17.04.2020
comment
хорошо, это совершенно другая библиотека, но я думаю, что это может быть полезно для более сложной файловой структуры. В моем случае оно того не стоит. В любом случае, спасибо за ваш ответ. Я думаю, это отличный ответ - person Kuba Šimonovský; 17.04.2020