【问题标题】:Xml to JSON Single Valued Array handlingXML 到 JSON 单值数组处理
【发布时间】:2016-03-07 08:31:47
【问题描述】:

我使用以下代码成功地将我的 XML 转换为 Json。

我遇到了这个问题,我在下面的程序中有两个不同的 XML 字符串。

第一个用户名有一个值,第二个有两个值。

第一个 xml 生成没有方括号的 json。第二个 xml 生成方括号。

我希望他们两个都有方括号。有没有办法将用户名强制转换为输出字符串中的数组?

首先,我希望它们看起来像输出 json 中的数组。

package com.java.json;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.xml.XMLSerializer;

public class XmlSerializer {

public static void main(String[] args) throws Exception {
String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">user@email.com</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
//String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">user@email.com</username><username xsi:type=\"xsd:string\">user@email.com</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";

JsonConfig conf =  new JsonConfig();
XMLSerializer xs = new XMLSerializer();

xs.setForceTopLevelObject(true);   
xs.setSkipWhitespace(true);
xs.setTrimSpaces(true);    
xs.setSkipNamespaces(true);
xs.setRemoveNamespacePrefixFromElements(true);

JSONObject jsonobj = (JSONObject) xs.read(xmlstring);    
String  jsonstring  = jsonobj.toString().replace("\"@", "\"");    

System.out.println(jsonstring);     

}
} 

第一个 XML 应该给出这样的输出。

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":[null],"password":null}}}}

目前是这样给的。

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":null,"password":null}}}}

上面程序中的第二个XML很好,它给出了这样的输出。

{"Envelope":{"Header":{"authInfo":{"type":"soap:authentication","username":[null,null],"password":null}}}}

提前致谢。

【问题讨论】:

  • 你为什么期望单个元素被序列化成一个数组?
  • 序列化后我们有一个下游进程,它期望用户名作为数组。如果它不在方括号内,该过程将失败。我们不介意在单值数组的情况下是否可以在序列化之后添加这些大括号。我们只需要把它放在方括号里。我们可以通过解析 json 并在最坏的情况下添加它们来手动进行操作,但我正在尝试一种更好的方法来将用户名的类型定义为输出 json 中的数组,例如将钱转换为数组并添加这些大括号。
  • 好的,如果您真的不想手动执行此操作.. 我认为这样的事情可能有效(但我不是 100% 确定)- 构建代表您的 XML/JSON 结构的类并将用户名字段声明为List&lt;String&gt;。然后使用jackson之类的框架将您的XML解析为此类的实例,然后将此对象序列化为JSON。这可以工作(也许有一些额外的配置)。但恕我直言 - 努力大于收益。

标签: java json xml serialization json-lib


【解决方案1】:

经过大量研究,我找到了解决问题的最佳方法。

您可以使用下面的代码 sn-p 将任何 XML 转换为 JSON,而不会丢失类型信息和数组问题。

我们需要 Java POJO 像下面这样转换。

通过使用下面代码中的 AuthInfo.class。我正在获取具有正确数据类型的 JSON。

您可以在此方法中将任何复杂的 XML 转换为 JSON。

package com.java.json;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.jaxb.XmlJaxbAnnotationIntrospector;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import com.tda.trident.beb.AuthInfo;

public class XmlDoc {

public static void main(String[] args) throws Exception {
    String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">user@email.com</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
    //String xmlstring = "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://services.web.post.list.com\"><soapenv:Header><authInfo xsi:type=\"soap:authentication\" xmlns:soap=\"http://list.com/services/SoapRequestProcessor\"><!--You may enter the following 2 items in any order--><username xsi:type=\"xsd:string\">user@email.com</username><username xsi:type=\"xsd:string\">user@email.com</username><password xsi:type=\"xsd:string\">password</password></authInfo></soapenv:Header></soapenv:Envelope>";
    Object messageObj = null;       

    XmlMapper unmarshaller = new XmlMapper();
    unmarshaller.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    XmlJaxbAnnotationIntrospector xmlIntrospector = new XmlJaxbAnnotationIntrospector();
    unmarshaller.setAnnotationIntrospector(xmlIntrospector);
    JaxbAnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
    ObjectMapper marshaller = new ObjectMapper().enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    marshaller.setSerializationInclusion(Include.NON_NULL);
    marshaller.setAnnotationIntrospector(introspector);

    TransactionTradeMessage rootNode = unmarshaller.readValue(xmlstring, AuthInfo.class);

    messageObj = rootNode.getTransactionTrade();

    System.out.println(marshaller.writeValueAsString(messageObj));

}
}

【讨论】:

  • 很难看到这个问题的任何真正答案!此解决方案是否作用于 XML 中的所有单值对象,或者是否有办法将其定位为仅作用于某些节点(xml)/值(JSON)
猜你喜欢
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2019-03-27
  • 2017-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多