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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39493173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 21:11:59  来源:igfitidea点击:

How to convert XML to JSON using only Hymanson?

javajsonxmlHymanson

提问by sudar

I am getting a response from server as XML. But I need to display this in JSON format.

我收到来自服务器的 XML 响应。但我需要以 JSON 格式显示它。

Is there any way to convert it without any third party API? I used Hymanson but for this I need to create POJO.

有没有办法在没有任何第三方 API 的情况下转换它?我使用了Hyman逊,但为此我需要创建 POJO。

The response from server is like this:

来自服务器的响应是这样的:

<?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>

回答by Stephen C

Is there any way to convert xml to json without using any third party API?

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

If you are being practical, no there isn't.

如果你是实用的,没有没有。

The step of parsing the XML can be performed using APIs that are part of Java SE. However going from the parsed XML (e.g. a DOM) to JSON requires a JSON support library, and Java SE does not include one.

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

(In theory you couldwrite such a library yourself, but what is the point of doing that?)

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



I used Hymanson but for this I need to create POJO.

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

@Cassio points out that Hymanson allows you to do this translation without writing POJOs. Alternatively, look at other (3rd-party) JSON APIs for Java; see http://www.json.orgfor a list of alternatives. Some of the simpler ones don't involve defining POJOs

@Cassio 指出 Hymanson 允许您在不编写 POJO 的情况下进行此翻译。或者,查看用于 Java 的其他(第 3 方)JSON API;有关替代方案的列表,请参阅http://www.json.org。一些更简单的不涉及定义 POJO

回答by cassiomolin

Using Hymanson 2.x

使用Hyman逊 2.x

You can do that with Hymanson and no POJOs are required for that:

你可以用 Hymanson 做到这一点,并且不需要 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);

The following dependencies are required:

需要以下依赖项:

<dependency>
    <groupId>com.fasterxml.Hymanson.core</groupId>
    <artifactId>Hymanson-core</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.Hymanson.core</groupId>
    <artifactId>Hymanson-databind</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.Hymanson.core</groupId>
    <artifactId>Hymanson-annotations</artifactId>
    <version>2.8.2</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.Hymanson.dataformat</groupId>
    <artifactId>Hymanson-dataformat-xml</artifactId>
    <version>2.8.2</version>
</dependency>

Be aware of the XmlMapperlimitations stated in the documentation:

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

Tree Model is only supported in limited fashion:specifically, Java arrays and Collectionscan be written, but can not be read, since it is not possible to distinguish Arrays and Objects without additional information.

仅以有限的方式支持树模型:特别是 Java 数组,Collections可以写入,但不能读取,因为没有附加信息就无法区分数组和对象。

Using JSON.org

使用 JSON.org

You also can do it with 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();

The following dependency is required:

需要以下依赖项:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>

回答by Ganesh

package com.src.test;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.apache.commons.io.IOUtils;

import net.sf.json.JSON;
import net.sf.json.xml.XMLSerializer;

public class JSONConverter {
    private static URL url = null;
    private static InputStream input = null;

    public static void main(String args[]) throws IOException {
        try {
            url = JSONConverter.class.getClassLoader().getResource("sampleXmlFilePath.xml");
            input = url.openStream();
            String xmlData = IOUtils.toString(input);

            XMLSerializer xmlSerializer = new XMLSerializer();
            JSON json = xmlSerializer.read(xmlData);
            System.out.println("JSON format : " + json);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            input.close();
        }
    }
}

回答by Tino M Thomas

I know that I am too late for an answer here. But I am writing this for the new guys who stumbled upon this question and thinking to use @Cassio's answer.

我知道我在这里回答已经太晚了。但我是为那些偶然发现这个问题并考虑使用@Cassio 答案的新人写这篇文章的。

The problem of using XmlMpperto de-serialize to a JsonNodeis that, when there are multiple elements with the same name at the same level, then it will replace the previous one with the new one and end up with data loss. Usually, we've to add this to an array. To tackle this problem, we can override the _handleDuplicateField()method of the JsonNodeDeserializerclass. Enough talking. Let's see the code

使用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);
    }
}

Since we've overridden the default deserializer, we also need to register this in the XmlMapperto make it work.

由于我们已经覆盖了默认的解串器,我们还需要在 中注册XmlMapper它以使其工作。

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new SimpleModule().addDeserializer(
    JsonNode.class, 
    new DuplicateToArrayJsonNodeDeserializer()
));
JsonNode node = xmlMapper.readTree(payLoad);

回答by prodigy4440

Using Hymanson

使用Hyman逊

import com.fasterxml.Hymanson.dataformat.xml.XmlMapper;
import java.io.IOException;

public class JsonUtil {

    private static XmlMapper XML_MAPPER = new XmlMapper();
    private static ObjectMapper JSON_MAPPER = new ObjectMapper();

    public static ObjectMapper getJsonMapper(){
        return JSON_MAPPER;
    }

    public static XmlMapper getXmlMapper(){
        return XML_MAPPER;
    }

    public static String xmlToJson(String xml){
        try {
            return getJsonMapper().writeValueAsString(getXmlMapper().readTree(xml));
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

回答by Prakasam Dhamodhiran

I have just followed cassiomolinsteps. I have faced below exception while using the Hymanson 2.x libraries.

我刚刚遵循了卡西莫林步骤。我在使用 Hymanson 2.x 库时遇到了以下异常。

Cannot create XMLStreamReader or XMLEventReader from a org.codehaus.stax2.io.Stax2ByteArraySource

If you also face the above exception. Add the below code to fix the issue. Then you can able to see the converted JSON without the namespace.

如果您也面临上述异常。添加以下代码以解决问题。然后您就可以在没有命名空间的情况下查看转换后的 JSON。

HymansonXmlModule module = new HymansonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);

Tips :If you want to convert the XML without the namespace then use Hymanson library. Dont go for org.json libs. It doesnt support this use case.

提示:如果您想在没有命名空间的情况下转换 XML,请使用 Hymanson 库。不要去 org.json 库。它不支持此用例。