在java中将带有命名空间的xml转换为json

Posted

技术标签:

【中文标题】在java中将带有命名空间的xml转换为json【英文标题】:Convert xml with namespaces to json in java 【发布时间】:2019-11-19 21:42:24 【问题描述】:

我正在尝试使用 java 将 xml 转换为 json,然后在修改后将 json 转换回 xml,应该给出相同的 xml。 xml 属性具有命名空间。

我的示例 xml:

<?xml version="1.0" encoding="UTF-8"?>
<ns2:testplan xmlns:ns2="http://jazz.net/xmlns/alm/qm/v0.1/" xmlns:ns1="http://schema.ibm.com/vega/2008/" xmlns:ns3="http://purl.org/dc/elements/1.1/" xmlns:ns4="http://jazz.net/xmlns/prod/jazz/process/0.6/" xmlns:ns5="http://jazz.net/xmlns/alm/v0.1/" xmlns:ns6="http://purl.org/dc/terms/" xmlns:ns7="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ns8="http://jazz.net/xmlns/alm/qm/v0.1/testscript/v0.1/" xmlns:ns9="http://jazz.net/xmlns/alm/qm/v0.1/executionworkitem/v0.1" xmlns:ns10="http://open-services.net/ns/core#" xmlns:ns11="http://open-services.net/ns/qm#" xmlns:ns12="http://jazz.net/xmlns/prod/jazz/rqm/process/1.0/" xmlns:ns13="http://www.w3.org/2002/07/owl#" xmlns:ns14="http://jazz.net/xmlns/alm/qm/qmadapter/v0.1" xmlns:ns15="http://jazz.net/xmlns/alm/qm/qmadapter/task/v0.1" xmlns:ns16="http://jazz.net/xmlns/alm/qm/v0.1/executionresult/v0.1" xmlns:ns17="http://jazz.net/xmlns/alm/qm/v0.1/catalog/v0.1" xmlns:ns18="http://jazz.net/xmlns/alm/qm/v0.1/tsl/v0.1/" xmlns:ns20="http://jazz.net/xmlns/alm/qm/styleinfo/v0.1/" xmlns:ns21="http://www.w3.org/1999/XSL/Transform">
<ns2:projectArea href="https://testserver:9080/qm/resource/itemOid/com.ibm.team.process.ProjectArea/_xv6jsJceEeimbPqnRT_G_Q" alias="projectArea"/>
<ns3:identifier>https://testserver:9080/qm/service/com.ibm.rqm.integration.service.IIntegrationService/resources/projectArea/testplan/urn:com.ibm.rqm:testplan:70?revision=294</ns3:identifier>
<ns2:stylesheet href="https://testserver:9080/qm/service/com.ibm.rqm.integration.service.IIntegrationService/resources/projectArea/testplan/urn:com.ibm.rqm:testplan:70?stylesheet=true"/>
<ns2:snapshot>
<ns3:title>testplan_70_&lt;Reason&gt;_&lt;Version&gt;_on_16 Apr 2019 05:50</ns3:title>
<ns5:updated>2019-04-16T12:20:01.644Z</ns5:updated>
<ns2:revision>294</ns2:revision>
</ns2:snapshot>
<ns2:webId>70</ns2:webId>
<ns3:title>Demo test plan 06</ns3:title>
<ns3:description/>
<ns2:creationDate>2019-01-22T10:36:40.289Z</ns2:creationDate>
<ns5:updated>2019-04-16T12:20:01.644Z</ns5:updated>
<ns5:state ns7:resource="https://testserver:9080/qm/service/com.ibm.rqm.integration.service.IIntegrationService/process-info/_xv6jsJceEeRT_G_Q/workflowstate/com.ibm.rqm.process.testplan.workflow/com.ibm.rqm.planning.common.underreview">com.ibm.rqm.planning.common.underreview</ns5:state>
<ns3:creator ns7:resource="https://testserver:9080/jts/resource/itemName/com.ibm.team.repository.Contributor/JLO1COB">abc</ns3:creator>
<ns5:owner>unassigned</ns5:owner>
<ns2:priority ns7:resource="https://testserver:9080/qm/service/com.ibm.rqm.integration.service.IIntegrationService/process-info/_xv6jsJceEeimbPqnG_Q/priority/literal.priority.101">literal.priority.101</ns2:priority>
<ns2:locked>false</ns2:locked>
<ns2:component href="https://testserver:9080/qm/service/com.ibm.rqm.integration.service.IIntegrationService/resources/projectArea/component/_yzQ3EZcmbPqnRT_G_Q"/>
</ns2:testplan>

有人可以帮助我使用java进行珍贵的转换。

我尝试过使用 org.json.XML 进行转换,但它没有提供正确的 json,其中 jsonobject 键/值具有命名空间。

我尝试过的代码没有给出响应:

JSONObject jsonObject = XML.toJSONObject("xml");

我希望有一种转换方式可以为 Json 提供正确的格式和具有命名空间的 json 对象,如果我隐藏这个 json 它应该给出初始 xml 请帮帮我。

【问题讨论】:

我的意思是,JSON 中没有命名空间之类的东西,所以... json 中没有命名空间之类的东西。但是如果我们将 xml 转换为 json..json 对象可以有命名空间。 我不明白你的意思。你应该提供例子。但是,当某些东西一开始就没有命名空间时,就没有什么神奇的情况可以让它现在有了命名空间。 JSON 没有命名空间。所以,没有什么能让它拥有命名空间。 是的,我知道,json 不会有命名空间。但是 jsonObject 或 keys 可以是正确的命名空间。我已经给出了上面的 xml,并且 xml 有命名空间。我需要将此 xml 转换为 json 并修改 json 中的某些值并将其转换回来。因此,当我将其转换回 xml 时,我需要正确地恢复命名空间以使其成为有效的 json 命名空间本质上是元素名称的一部分:它们总是相同的。不要将命名空间放在 JSON 中,而只使用足够独特的名称,无需在命名空间中分隔它们。然后在将其转换回 XML 时,将名称空间放回去。没有库会为您进行这样的转换,首先从 XML 转换为对象,然后从对象转换为 JSON,反之亦然。 【参考方案1】:

你可以试试 jackson 的 XmlMapper (com.fasterxml.jackson.dataformat.xml.XmlMapper)

XmlMapper xmlMapper = new XmlMapper();
JsonNode jsonNode = xmlMapper.readTree(string.getBytes());
ObjectMapper objectMapper = new ObjectMapper();
String value = objectMapper.writeValueAsString(jsonNode);

编辑:我使用过的依赖项

<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
</dependency>
<dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.9.0</version>
</dependency>

【讨论】:

您好,感谢您的快速回复。你能告诉我所有依赖项需要什么吗? 应该是“Jackson Dataformat XML”版本 2.9.0(或更高版本?)编辑:添加了对答案的依赖。 我已经添加了您建议的依赖项。但我现在遇到错误。引起:java.lang.ClassNotFoundException: org.codehaus.stax2.io.Stax2ByteArraySource 在这一行 JsonNode jsonNode = xmlMapper.readTree(string.getBytes()); 你的 XmlMapper 是从哪里导入的?添加了另一个依赖项。 @Ajith,您需要“stax2-api”jar 文件。如果你有一个 Maven 项目,它会下载额外的 jar 文件。我的项目不是 Maven,我只按照建议导入了这 2 个 jar 文件(jackson-databind 和 jackson-dataformat-xml)并得到了同样的错误。创建 Maven 项目并尝试添加依赖项后,我看到了其他 jar 文件。 stax2-api-3.1.4.jar 就是其中之一,可能您还需要其他 jars。【参考方案2】:

获取JSONObject 并将其转换为 JSON 字符串:

JSONObject jsonObject = XML.toJSONObject("xml");
String jsonString = jsonObject.toString();

如果您想漂亮地打印字符串,请使用toString(int),它将空格数作为参数。

String prettyPrintedJson = jsonObject.toString(4);

【讨论】:

未解决问题主题...【参考方案3】:

这个问题有点老了,但我想分享一下我最近做的同一任务的答案! 要求是: 拥有这个 xml:

<ns2:testplan>
 <ns2:snapshot>
    <ns2:revision>294</ns2:revision>
 </ns2:snapshot>
 <ns2:webId>70</ns2:webId>
 <ns2:title>Demo test plan 06</ns2:title>
</ns2:testplan>

我们想把它转换成:


  "ns2:testplan": 
    "ns2:snapshot": 
      "ns2:revision": 294
    ,
    "ns2:title": "Demo test plan 06",
    "ns2:webId": 70
  

请注意,对于接受的响应,根标签 &lt;ns2:testplan&gt; 和命名空间前缀不包含在 JSON 中。 要配置 XmlMapper 以保留命名空间并添加根标签,请按以下步骤操作:

var module = new SimpleModule().addDeserializer(JsonNode.class, new JsonNodeDeserializer() 
        @Override
        public JsonNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException 
            return ctxt.getNodeFactory()
                    .objectNode()
                    .set("ns2:testplan", super.deserialize(p, ctxt)); // this config adds the root tag
        
    );

XMLInputFactory xmlInputFactory = new WstxInputFactory();
xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); // this one keeps the namespace prefix
XmlMapper xmlMapper = new XmlMapper(new XmlFactory(xmlInputFactory, new WstxOutputFactory()));
xmlMapper.registerModule(module);

然后使用接受答案的代码将 XML 转换为 JSON。

【讨论】:

以上是关于在java中将带有命名空间的xml转换为json的主要内容,如果未能解决你的问题,请参考以下文章

带有命名空间和前缀的 Json 到 XML

将带有命名空间和属性的 XML 转换为 C# 模型类

XML名命空间

如何在 Ruby 中将 JSON 转换为 XML?

在 PHP 中将 JSON 转换为 XML,但在 XML 中为 JSON 数组创建一个容器元素

在 Android 中将 XML 转换为 JSON 会出错