如何仅使用Jackson将XML转换为JSON?

sud*_*dar 12 java xml json jackson

我从服务器获得XML响应.但我需要以JSON格式显示它.

有没有办法在没有任何第三方API的情况下进行转换?我用过杰克逊,但为此我需要创建POJO.

服务器的响应是这样的:

<?xml version='1.0'?>
<errors><error><status>400</status><message>The field 'quantity' is invalid.</message><details><invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason><available_quantity>0</available_quantity><order_product_id>12525</order_product_id></details></error></errors>
Run Code Online (Sandbox Code Playgroud)

cas*_*lin 24

使用Jackson 2.x

你可以用Jackson做到这一点,并且不需要POJO:

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
             "<errors>\n" +
             "  <error>\n" +
             "    <status>400</status>\n" +
             "    <message>The field 'quantity' is invalid.</message>\n" +
             "    <details>\n" +
             "      <invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason>\n" +
             "      <available_quantity>0</available_quantity>\n" +
             "      <order_product_id>12525</order_product_id>\n" +
             "    </details>\n" +
             "  </error>\n" +
             "</errors>";

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xml.getBytes());

ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(node);
Run Code Online (Sandbox Code Playgroud)

需要以下依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.8.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

请注意文档中XmlMapper陈述的限制:

树模型仅以有限的方式支持:特别是Java数组并且Collections可以编写,但无法读取,因为在没有附加信息的情况下无法区分数组和对象.

使用JSON.org

您也可以使用JSON.org执行此操作:

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
             "<errors>\n" +
             "  <error>\n" +
             "    <status>400</status>\n" +
             "    <message>The field 'quantity' is invalid.</message>\n" +
             "    <details>\n" +
             "      <invalid_reason>The quantity specified is greater than the quantity of the product that is available to ship.</invalid_reason>\n" +
             "      <available_quantity>0</available_quantity>\n" +
             "      <order_product_id>12525</order_product_id>\n" +
             "    </details>\n" +
             "  </error>\n" +
             "</errors>";

String json = XML.toJSONObject(xml).toString();
Run Code Online (Sandbox Code Playgroud)

需要以下依赖项:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

  • 使用Jackson选项的BIG WARNING是XML通常具有重复键,当Jackson将具有重复键的XML转换为JSON时,它们将被覆盖. (3认同)
  • @samunp 只是让您知道,Jackson 2.x 的 XML 支持是作为单独的工件发布的。换句话说,即使你使用 Jackson 2.x,如果你想使用 `XmlMapper`,你也需要包含 `jackson-dataformat-xml` 依赖项。 (2认同)
  • 上述警告是合法的,但请注意 Jackson 2.12 最终改进了处理(请参阅 https://cowtowncoder.medium.com/jackson-2-12-improved-xml-b9487889a23f),以便如果使用 `JsonNode` 或 `Object` 则保留重复项作为目标类型。 (2认同)

Tin*_*mas 7

我知道我来不及在这里回答。但是我是为那些偶然发现这个问题并想使用@Cassio答案的新人写的。

使用XmlMpper反序列化为a的问题JsonNode是,当在同一级别有多个具有相同名称的元素时,它将用新元素替换前一个元素,并最终导致数据丢失。通常,我们必须将此添加到数组中。为了解决这个问题,我们可以重写类的_handleDuplicateField()方法JsonNodeDeserializer。聊够了。让我们看一下代码

public class DuplicateToArrayJsonNodeDeserializer extends JsonNodeDeserializer {

    @Override
    protected void _handleDuplicateField(JsonParser p, DeserializationContext ctxt, 
        JsonNodeFactory nodeFactory,String fieldName, ObjectNode objectNode,
        JsonNode oldValue, JsonNode newValue) throws JsonProcessingException {
        ArrayNode node;
        if(oldValue instanceof ArrayNode){
            node = (ArrayNode) oldValue;
            node.add(newValue);
        } else {
            node = nodeFactory.arrayNode();
            node.add(oldValue);
            node.add(newValue);
        }
        objectNode.set(fieldName, node);
    }
}
Run Code Online (Sandbox Code Playgroud)

由于我们已经覆盖了默认的反序列化器,因此我们还需要在中进行注册XmlMapper才能使其正常工作。

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new SimpleModule().addDeserializer(
    JsonNode.class, 
    new DuplicateToArrayJsonNodeDeserializer()
));
JsonNode node = xmlMapper.readTree(payLoad);
Run Code Online (Sandbox Code Playgroud)

  • 非常好!另请注意,从上面的 Jackson 2.12 开始,也是由 XML 模块完成的(请参阅 https://cowtowncoder.medium.com/jackson-2-12-improved-xml-b9487889a23f) (2认同)

Ste*_*n C 3

有没有办法在不使用任何第三方API的情况下将xml转换为json?

如果你很实际的话,不,没有。

解析 XML 的步骤可以使用 Java SE 的 API 来执行。然而,从解析的 XML(例如 DOM)到 JSON 需要一个 JSON 支持库,而 Java SE 不包含该库。

(理论上你可以自己编写这样一个库,但是这样做有什么意义呢?)


我使用了 Jackson,但为此我需要创建 POJO。

@Cassio 指出 Jackson 允许您无需编写 POJO 即可完成此翻译。或者,查看其他(第 3 方)Java JSON API;请参阅http://www.json.org以获取替代方案列表。一些更简单的不涉及定义 POJO