【问题标题】:After I got XML data, how to parse it and transfer to JSON?得到 XML 数据后,如何解析并转成 JSON?
【发布时间】:2011-08-04 18:34:41
【问题描述】:

在 Jersey RESTful 框架中,我知道我可以在客户端获取 xml 数据,如下所示:

private static final String BaseURI = "http://DOMAN.com";

ClientConfig config = new DefaultClientConfig();

Client client = Client.create(config);

WebResource service = client.resource(BaseURI);

String xmlData = service.path("rest").path("todos").accept(
                MediaType.APPLICATION_XML).get(String.class)

我的问题是我该如何解析 xmlData 呢?我想从xmlData 获取所需的数据,并将所需的数据传输到 JSON,最好的实现方式是什么?

【问题讨论】:

  • 为什么不直接向 Jersey 询问数据的 json 表示形式?
  • 因为底层接口传输给我需要转换成json的xml数据
  • 你可以使用 Sax OR Dom 解析器来解析数据

标签: java xml json jakarta-ee jersey


【解决方案1】:

作为一般规则,如果没有必要,切勿直接从 XML 转换为 JSON(反之亦然)。 而是将数据从 XML 或 JSON 绑定到 POJO,然后进行其他转换。虽然看起来不直观,但这会导致更清晰的结果和更少的问题,因为 POJO 和数据格式之间的转换有更多的选择、成熟的、精心设计的库; POJO 更容易配置(带有注释)并且有更多的元数据来指导转换过程。 直接转换库(如 Jettison,见下文)受到各种问题的困扰;通常会生成“franken-JSON”,即技术上正确但看起来很陌生的 JSON,因为转换需要添加构造。

如果是 Jersey,则使用 JAXB 处理与 POJO 之间的 XML,并使用 Jackson 处理 JSON。无论如何,这些都是泽西使用的图书馆;直接使用也很简单。

如果您绝对坚持直接转换,您可以尝试Jettison,但如果需要,请准备好解决列表、数组和映射的问题(尤其是单元素数组——数组在 XML 中存在问题) ,而自动转换经常出错)。

【讨论】:

    【解决方案2】:

    如果您的服务尚未提供 JSON 作为选项(如果您将 MediaType.APPLICATION_XML 更改为 MediaType.APPLICATION_JSON 会发生什么情况?),那么我相信您有一些选项,我将按照自己的偏好列出这些选项。

    选项 1:您有数据的 XML 架构 如果您有返回 XML 的 XML 模式,则可以使用 xjc 生成带有 JAXB 注释的 java 类,然后利用 jackson 将实例转换为 JSON 数据。我认为通过利用这个库而不是自己进行解析,这会让你快速前进。 Jackson 是一个强大的库,被 glassfish 用于他们的 Jersey(JAX-RS) 实现,我认为依赖这个库没有任何风险。

    选项 2:使用 json.org 库,但我在这个库与它的基于反射的方法等方面有很大的问题。也就是说,它可能对你很有效......你可以测试相对容易,看看它是否满足您的要求。如果是这样......你就完成了! =)

    选项 3:您没有 XML 架构和/或您想要更多控制权 正如@Falcon 指出的那样,您始终可以使用传统的 XML 解析技术将 XML 解析为您想要的任何内容。我偏爱 SAX 解析,但 DOM 可以根据 xml 端工作

    问候,

    史蒂夫

    【讨论】:

    • 您好,感谢您的回答,您能否为您的选项 1 提供示例或教程?
    • @Steve Siebert,我会等待您的进一步回复,谢谢。
    • @Mellon - 是的,没问题。我从一个实际的教程开始,并希望确保这个场景能够涵盖您正在寻找的内容,因为它也可以用于本地培训。您正在编写一个移动应用程序,并且需要使用仅提供 XML 的第 3 方 RESTful Web 服务。为了节省带宽和处理,您决定使用 Jersey 创建一个 RESTful 代理,该代理从您的移动应用程序接收请求,向第 3 方 RESTful 端点发出请求,并返回 JSON。您认为这会满足您的需求吗?
    • @Steve siebert,我正在编写一个 Web 应用程序。我需要使用仅返回给我 XML 数据的第 3 方 RESTful Web 服务(将来可能通过使用 RMI 来返回 POJO)。我的网络应用程序的 javascript 向我的 RESTful 运动衫发送 ajax 调用以请求 JSON 数据。然后,我的球衣服务器向该第 3 方服务发送请求,该服务将 xml 数据作为响应返回给我。因此,我的球衣服务器需要解析返回的 xml 数据并将其转换为 JSON 数据,然后将其传递给我的 Javascript 作为我的 Web 应用程序中的响应。
    • @Steve siebert,由于我没有第 3 方 JAXB bean 模型,所以我想知道,在获得 xml 数据后,如何解析它以获取xml 数据。例如,我的球衣可以获取TOYOTA13这样的xml数据,那么如何从xml字符串数据中获取车名值呢?我没有第 3 方 JAXB 光束模型,我不能使用 "JAXBElement jaxbContact = r .path("13") .type(MediaType.APPLICATION_XML) .get(generic);"
    【解决方案3】:

    最简单的方法是使用 org.json 包:http://json.org/javadoc/org/json/XML.html

    XML.toJSONObject(xmlData).toString()
    

    除了必要的 import 语句之外,仅这一行就可以完成所有工作。

    既然我已经提到了 org.json 库,很多人可能会对它发表评论。请记住,我说的是最简单和最简单的方法,而不是最好或最高效的方法;-)

    如果您使用的是 maven,请添加此依赖项:

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

    【讨论】:

      【解决方案4】:

      您是否可以访问生成 XML 的“低级接口”?如果这样做,唯一需要的更改是使用“@XmlRootElement”注释 xml 对象。然后,您可以直接将 XML 对象作为 JSON 传回,而无需任何其他代码。

      【讨论】:

        【解决方案5】:

        检查Jsonix。如果您有 XML 模式,则可以在 JavaScript 中生成 XML-JSON 映射和解组/编组 XML。与 JAXB(Steve Siebert 提到的)非常相似,但在客户端上工作。

        // The PO variable provides Jsonix mappings for the purchase order test case
        // Its definition will be shown in the next section
        
        var PO = { };
        
        // ... Declaration of Jsonix mappings for the purchase order schema ...
        
        // First we construct a Jsonix context - a factory for unmarshaller (parser)
        // and marshaller (serializer)
        var context = new Jsonix.Context([ PO ]);
        
        // Then we create an unmarshaller
        var unmarshaller = context.createUnmarshaller();
        
        // Unmarshal an object from the XML retrieved from the URL
        unmarshaller.unmarshalURL('/org/hisrc/jsonix/samples/po/test/po-0.xml',
            // This callback function will be provided with the result
            // of the unmarshalling
            function(result) {
                // We just check that we get the values we expect
                assertEquals('Alice Smith', result.value.shipTo.name);
                assertEquals('Baby Monitor', result.value.item[1].productName);
            });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-22
          • 2017-02-19
          • 2012-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多