Как настроить Jackson XmlMapper для использования типов данных из XML-схемы - PullRequest
0 голосов
/ 05 июня 2018

У меня есть xml-сообщение, которое необходимо преобразовать в формат сообщения json.В сообщении xml определена схема xml, содержащая информацию о типе элементов.Тем не менее, результирующий JSON имеет все значения в виде текстовых значений вместо логического / числа, как указано в схеме XML.Как я могу дать XmlMapper () информацию о типе из схемы xml?

XmlMapper xmlMapper = new XmlMapper();
String xmlMsg = getResourceContent("test.xml");        
JsonNode node = xmlMapper.readTree(xmlMsg.getBytes());
ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);

Образец xml:

<myMessage>
     <id>333</id>
     <type>Text</type>
     <flag>true</flag>
</myMessage>

Результирующий json:

{
  "id": "333",
  "type": "Text",
  "flag": "true"
}

Ожидаемый JSON:

{
  "id": 333,
  "type": "Text",
  "flag": true
}

Ответы [ 2 ]

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

Если ваша XML-схема проста, достаточно конвертировать «true / false» в «boolean» и «number» в «long».У меня есть решение.

После JsonNode node = xmlMapper.readTree(xmlMsg.getBytes()); потомки node имеют тип TextNode.Вы можете перемещать node объект и конвертировать TextNode в BooleanNode или LongNode, если значение соответствует определенным условиям.

Добавьте следующий метод:

public static JsonNode resolveType(JsonNode jsonNode) {
    if (jsonNode instanceof ObjectNode) {
        ObjectNode objectNode = (ObjectNode) jsonNode;
        Iterator<Entry<String, JsonNode>> fields = objectNode.fields();
        while (fields.hasNext()) {
            Entry<String, JsonNode> next = fields.next();
            next.setValue(resolveType(next.getValue()));
        }
    } else if (jsonNode instanceof TextNode) {
        TextNode textNode = (TextNode) jsonNode;
        String value = textNode.textValue();
        if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) {
            jsonNode = BooleanNode.valueOf(Boolean.valueOf(value));
        } else if (StringUtils.isNumeric(value)) {
            jsonNode = LongNode.valueOf(Long.valueOf(value));
        }
    }
    return jsonNode;
}

Затем используйтеэтот метод для разрешения типа JsonNode node:

JsonNode node = xmlMapper.readTree(xmlMsg.getBytes());
node = resolveType(node); // <--- Add this statement to your code.
ObjectMapper jsonMapper = new ObjectMapper();
//...

Выходные данные должны быть ожидаемыми JSON:

{"id":333,"type":"Text","flag":true}

0 голосов
/ 31 октября 2018

Я создал класс POJO, где я объявил свои типы данных в Message.java:

public class Message {
    private Integer id;
    private String type;
    private Boolean flag;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }
}

и в вашем коде:

//src the XML String to Parse
XmlMapper xmlMapper = new XmlMapper();
Message myMessage = xmlMapper.readValue(src, Message.class);

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(myMessage);

System.out.println(json);

результат:

{"id":333,"type":"Text","flag":true}
...