XML 和 JSON 互转

Java常用方法   2025-01-12 05:33   148   0  

一、org.json

1、依赖

json-20220924.jar

2、示例代码

import org.json.JSONObject;
import org.json.XML;

public class JsonToXmlTool {

    /**
     * JSON对象转换为xml字符串
     * @param jo0 待转换JSON对象
     * @return 转换后的xml字符串
     */
    public static String jsonToXml(JSONObject jo0) {
        return XML.toString(jo0);
    }


    /**
     * xml字符串转JSON对象
     * @param xml xml字符串
     * @return 转换后的JSON对象
     */
    public static JSONObject xmlToJson(String xml) {
        return XML.toJSONObject(xml);
    }

}

二、fastjson

1、依赖

commons-lang3-3.12.0.jar
dom4j-2.1.3.jar
fastjson-1.2.83.jar

2、示例代码

package com.chenwc;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class JsonToXmlTool {

    /**
     * JSON对象转换为xml字符串(xml没有属性)
     * @param jo 待转换JSON对象
     * @return 转换后的xml字符串
     */
    public static String JsonToXml(JSONObject jo) {
        StringBuilder xmlStr = new StringBuilder();
        for (String key : jo.keySet()) {
            Object object = jo.get(key);
            if (object instanceof JSONObject){
                xmlStr.append("<");
                xmlStr.append(key);
                xmlStr.append(">");
                xmlStr.append(JsonToXml((JSONObject) object));
                xmlStr.append("</");
                xmlStr.append(key);
                xmlStr.append(">");
            }
            else if (object instanceof JSONArray){
                JSONArray ja = (JSONArray) object;
                for (Object o : ja) {
                    JSONObject jo2 = new JSONObject();
                    jo2.put(key, o);
                    xmlStr.append(JsonToXml(jo2));
                }
            }
            else {
                xmlStr.append("<");
                xmlStr.append(key);
                xmlStr.append(">");
                xmlStr.append(object);
                xmlStr.append("</");
                xmlStr.append(key);
                xmlStr.append(">");
            }
        }

        return xmlStr.toString();
    }

    /**
     * JSON对象(键以@开头的是属性)转换为xml字符串(xml有属性),用于解析本类xmlToJson转换的带有属性的JSON对象
     * @param jo 待转换JSON对象
     * @return 转换后的xml字符串
     */
    public static String jsonToXmlContainAttributes(JSONObject jo) {
        StringBuilder xmlStr = new StringBuilder();

        for (String key : jo.keySet()) {
            Object object = jo.get(key);
            //键不以@开头,则这个键是节点对象,不是属性
            if (!key.startsWith("@")){
                //JSON对象
                if (object instanceof JSONObject){
                    JSONObject jsonObject = (JSONObject) object;
                    StringBuilder attributes = new StringBuilder();
                    //获取所有属性
                    for (String attributesKey : jsonObject.keySet()) {
                        if (attributesKey.startsWith("@")) {
                            attributes.append(attributesKey.replace("@", "")).append("=\"").append(jsonObject.get(attributesKey)).append("\" ");
                        }
                    }
                    //如果这个JSON对象包含content键,则说明这个JSON对象是有属性和值的
                    if (jsonObject.containsKey("content")){
                        xmlStr.append("<");
                        xmlStr.append(key);
                        //属性不为空,加上属性
                        if (StringUtils.isNotEmpty(attributes.toString())){
                            xmlStr.append(" ").append(attributes).append(" ");
                        }
                        xmlStr.append(">");
                        xmlStr.append(jsonObject.getString("content"));
                        xmlStr.append("</");
                        xmlStr.append(key);
                        xmlStr.append(">");
                    }
                    //如果这个JSON对象不包含content键,则说明这个JSON对象没有值
                    else {
                        xmlStr.append("<");
                        xmlStr.append(key);
                        //属性不为空,加上属性
                        if (StringUtils.isNotEmpty(attributes.toString())){
                            xmlStr.append(" ").append(attributes).append(" ");
                        }
                        xmlStr.append(">");
                        xmlStr.append(jsonToXmlContainAttributes((JSONObject) object));
                        xmlStr.append("</");
                        xmlStr.append(key);
                        xmlStr.append(">");
                    }
                }
                //JSON数组
                else if (object instanceof JSONArray){
                    JSONArray ja = (JSONArray) object;
                    for (Object o : ja) {
                        JSONObject jo2 = new JSONObject();
                        jo2.put(key, o);
                        xmlStr.append(jsonToXmlContainAttributes(jo2));
                    }
                }
                //值
                else {
                    xmlStr.append("<");
                    xmlStr.append(key);
                    xmlStr.append(">");
                    xmlStr.append(object);
                    xmlStr.append("</");
                    xmlStr.append(key);
                    xmlStr.append(">");
                }
            }
        }
        return xmlStr.toString();
    }

    /**
     * xml字符串转JSON对象
     *
     * @param xml xml字符串
     * @return 转换后的JSON对象
     */
    public static JSONObject xmlToJson(String xml) {
        try {
            // 创建一个SAXReader解析器
            SAXReader reader = new SAXReader();
            // 读取xml文件,转换成Document结点
            Document doc = reader.read(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
            // 获取XML文档的根节点对象
            Element root = doc.getRootElement();
            JSONObject rootJsonObject = new JSONObject();
            return (JSONObject) dom4j2Json(root, rootJsonObject);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 递归解析所有节点
     * @param ele 节点对象
     * @param json JSON对象
     * @return 转换后的JSON对象
     */
    private static Object dom4j2Json(Element ele, JSONObject json) {
        JSONObject resultJsonObject = new JSONObject();
        // 获取节点所有属性
        for (Attribute o : ele.attributes()) {
            resultJsonObject.put("@" + o.getName(), o.getText());
        }
        // 获取子节点
        List<Element> chdEl = ele.elements();
        // 没有子节点
        if (chdEl.isEmpty()) {
            if (StringUtils.isNotEmpty(ele.getText())) {
                resultJsonObject.put(ele.getName(), ele.getText());
            }
        }
        // 有子节点
        for (Element e : chdEl) {
            // 子节点没有子节点
            if (e.elements().isEmpty()) {
                JSONObject childJsonObject = new JSONObject();
                // 获取节点所有属性
                for (Attribute o : e.attributes()) {
                    childJsonObject.put("@" + o.getName(), o.getText());
                }
                if (StringUtils.isNotEmpty(e.getText())) {
                    childJsonObject.put("content", e.getText());
                }
                //第一次循环进入时没有该节点名称,第二次循环进入时如果存在同名的节点,则是数组
                if(resultJsonObject.containsKey(e.getName())) {
                    Object oe = resultJsonObject.get(e.getName());
                    resultJsonObject.put(e.getName(), convertJsonArray(oe, childJsonObject));
                }
                else {
                    //该节点是空节点或者没有属性
                    if(childJsonObject.isEmpty() || e.attributes().isEmpty()) {
                        if (StringUtils.isNotEmpty(e.getText())) {
                            resultJsonObject.put(e.getName(), e.getText());
                        }
                    }
                    //该节点有属性
                    else {
                        resultJsonObject.put(e.getName(), childJsonObject);
                    }
                }
            }
            // 子节点还有子节点
            else {
                JSONObject childObject = new JSONObject();
                dom4j2Json(e, childObject);
                JSONObject childJsonObject = childObject.getJSONObject(e.getName());
                //第一次循环进入时没有该节点名称,第二次循环进入时如果存在同名的节点,则是数组
                if(resultJsonObject.containsKey(e.getName())) {
                    Object oe = resultJsonObject.get(e.getName());
                    resultJsonObject.put(e.getName(), convertJsonArray(oe, childJsonObject));
                }
                else {
                    resultJsonObject.put(e.getName(), childJsonObject);
                }
            }
        }
        json.put(ele.getName(), resultJsonObject);

        return json;
    }

    /**
     * 解析JSON数组
     * @param oe JSON对象
     * @param childJsonObject 数组元素
     * @return 转换后的JSON数组
     */
    private static JSONArray convertJsonArray(Object oe, JSONObject childJsonObject){
        JSONArray childJsonArray = new JSONArray();
        //数组第二个元素
        if(oe instanceof JSONObject) {
            JSONObject oeJsonObject = (JSONObject)oe;
            childJsonArray.add(oeJsonObject);
            childJsonArray.add(childJsonObject);
        }
        //数组第x个元素(x>2)
        if(oe instanceof JSONArray) {
            childJsonArray = (JSONArray)oe;
            childJsonArray.add(childJsonObject);
        }
        if(oe instanceof String) {
            String eString = (String)oe;
            childJsonArray.add(eString);
            childJsonArray.add(childJsonObject);
        }
        return childJsonArray;
    }
}

3、测试

package com.chenwc;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Test {
    private static final Logger log = LoggerFactory.getLogger(Test.class);
    public static void main(String[] args) {


        String jsonString = "{\"ESB\":{\"DATA\":{\"DATAINFOS\":{\"PUUID\":\"\",\"DATAINFO\":[{\"Abbreviation\":\"深圳润园四季餐饮有限公司\",\"CityCode\":\"440300\",\"CooperationStatus\":\"合作中\",\"CATEGORYCODE\":\"00\",\"MULTICODE\":{\"VALUELIST\":[{\"ContactMobile\":\"17365452345\",\"IsPrimaryContact\":\"是\",\"SfaContactId\":\"9173566440704169777\",\"SPECIALITYCODE\":\"CONTACTINFO\",\"LISTCODE\":\"VE244A9Y3FNUWN7K747KFU6H6L84RHI5\",\"ContactEMail\":\"22133133@qq.com\",\"ContactName\":\"李迪\"},{\"ContactMobile\":\"17365459878\",\"IsPrimaryContact\":\"否\",\"SfaContactId\":\"6788874131617504418\",\"SPECIALITYCODE\":\"CONTACTINFO\",\"LISTCODE\":\"6WQB8MA09Z4776I430SJPC2TU6K93UU4\",\"ContactEMail\":\"2233133@qq.com\",\"ContactName\":\"吴繁荣\"},{\"SiteContactName\":\"刘三\",\"SiteAddress\":\"测试77777\",\"SfaSiteId\":\"8480089929551622116\",\"SPECIALITYCODE\":\"SITEINFO\",\"SiteCityCode\":\"110000\",\"LISTCODE\":\"WAHVUTQXQP7S0GQ36Z562W0S9OZ3QYEG\",\"SiteContactMobile\":\"21878128337\"}]},\"FILES\":[{\"STOREPATH\":\"6055786081413437802/cm/202210/ea56e72f4c2249ad8dc732517b36a634.jpg\",\"FILETYPE\":\"image/jpg\"},{\"STOREPATH\":\"6055786081413437802/cm/202301/59d94e4583cf42d2aa321694c8f5f483.jpg\",\"FILETYPE\":\"image/jpg\"}]}]}}}}";

        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        log.info("JsonString: " + jsonObject.toJSONString());
        log.info("JsonToXml: " + JsonToXmlTool.JsonToXml(jsonObject));

        String xmlString = "<alexa ver=\"0.9\" url=\"http://coursesweb.net/\" home=\"0\" aid=\"1\">  \r\n"
                + "  <sd title=\"a\" host=\"coursesweb.net\">  \r\n"
                + "    <title>CoursesWeb: php, mysql, html, css, javascript, ajax, jquery, actionscript, flash</title>  \r\n"
                + "    <linksin />  \r\n" + "    <speed pct=\"51\">4578</speed>  \r\n" + "  </sd>  \r\n"
                + "  <sd>  \r\n" + "    <popularity>5777</popularity>  \r\n" + "    <reach rank=\"5952\"/>  \r\n"
                + "    <rank url=\"http://coursesweb.net/\">6667</rank>  \r\n"
                + "  </sd>  <child attr=\"23232\">5353543</child><child test=\"hahahaha\">子节点也没有子节点</child><child test=\"2222\">222子节点也没有子节点222</child>\r\n"
                + "</alexa>";
        String xmlString2 = "<ESB><DATA><DATAINFOS><PUUID /><DATAINFO><Abbreviation>深圳润园四季餐饮有限公司</Abbreviation><CityCode>440300</CityCode><CooperationStatus>合作中</CooperationStatus><TpmMainCategory>辅食</TpmMainCategory><Address>天安社区车公庙泰然七路1号博今商务广场三层03号商铺</Address><Customer>深圳润园四季餐饮有限公司</Customer><TpmKeyCustomer /><SendSystemName>ERP,TPM,SFA</SendSystemName><SfaId>8941778068727647925</SfaId><TaxPayerType>一般纳税人</TaxPayerType><PaymentTerms>EOM45</PaymentTerms><IsKeyCustomer>否</IsKeyCustomer><BusinessCorporation>黄日高</BusinessCorporation><InvoiceBankAccount>381626368</InvoiceBankAccount><InvoiceMobile>36176767</InvoiceMobile><MarketingDepartment>PRC Offline Sales</MarketingDepartment><InvoiceBankName>测试20221014</InvoiceBankName><Credit>30</Credit><CertificateNumber>914403005571835453</CertificateNumber><InvoiceSubBankName>测试20221014</InvoiceSubBankName><CountryCode>CN</CountryCode><SFASalesPath>全部,PRC Offline South,粤东,深圳市</SFASalesPath><MarketingType>母婴-单店</MarketingType><ChargePerson>Andy Liu(刘平)</ChargePerson><InvoiceTaxNumber>636772617</InvoiceTaxNumber><CATEGORYCODE>00</CATEGORYCODE><MULTICODE><VALUELIST><PaymentAccountCode>30000866</PaymentAccountCode><SPECIALITYCODE>PAYMENTINFO</SPECIALITYCODE><LISTCODE>5I6FT34K4U5F7P0E23NT768513Y1661U</LISTCODE></VALUELIST><VALUELIST><BussinessUnit>BU_SFPRCSH</BussinessUnit><SPECIALITYCODE>FINANCEINFO</SPECIALITYCODE><LISTCODE>43359CW4X0NMA89R88H46W66888SB2B8</LISTCODE></VALUELIST><VALUELIST><ContactMobile>17365452345</ContactMobile><IsPrimaryContact>是</IsPrimaryContact><SfaContactId>9173566440704169777</SfaContactId><SPECIALITYCODE>CONTACTINFO</SPECIALITYCODE><LISTCODE>VE244A9Y3FNUWN7K747KFU6H6L84RHI5</LISTCODE><ContactEMail>22133133@qq.com</ContactEMail><ContactName>李迪</ContactName></VALUELIST><VALUELIST><ContactMobile>17365459878</ContactMobile><IsPrimaryContact>否</IsPrimaryContact><SfaContactId>6788874131617504418</SfaContactId><SPECIALITYCODE>CONTACTINFO</SPECIALITYCODE><LISTCODE>6WQB8MA09Z4776I430SJPC2TU6K93UU4</LISTCODE><ContactEMail>2233133@qq.com</ContactEMail><ContactName>吴繁荣</ContactName></VALUELIST><VALUELIST><SiteContactName>刘三</SiteContactName><SiteAddress>测试77777</SiteAddress><SfaSiteId>8480089929551622116</SfaSiteId><SPECIALITYCODE>SITEINFO</SPECIALITYCODE><SiteCityCode>110000</SiteCityCode><LISTCODE>WAHVUTQXQP7S0GQ36Z562W0S9OZ3QYEG</LISTCODE><SiteContactMobile>21878128337</SiteContactMobile></VALUELIST><VALUELIST><SiteContactName>刘飒</SiteContactName><SiteAddress>测试00333003</SiteAddress><SfaSiteId>7037924554341270073</SfaSiteId><SPECIALITYCODE>SITEINFO</SPECIALITYCODE><SiteCityCode>330300</SiteCityCode><LISTCODE>8Y2PT3L762Y3IRBP9Y3FSHX90320997H</LISTCODE><SiteContactMobile>15876542345</SiteContactMobile></VALUELIST></MULTICODE><FILES><STOREPATH>https://image.waiqin365.com/6055786081413437802/cm/202210/ea56e72f4c2249ad8dc732517b36a634.jpg</STOREPATH><FILETYPE>image/jpg</FILETYPE><FILENAME>营业执照.jpg</FILENAME></FILES><FILES><STOREPATH>https://image.waiqin365.com/6055786081413437802/cm/202301/59d94e4583cf42d2aa321694c8f5f483.jpg</STOREPATH><FILETYPE>image/jpg</FILETYPE><FILENAME>开票资料(图片).jpg</FILENAME></FILES><CustomerType>真实客户</CustomerType><InvoiceType>增值税专用发票</InvoiceType><TpmChannelType>Offline-GT</TpmChannelType><CODE>10001267</CODE><InvoiceAddress>测试20221014</InvoiceAddress><TaxClassificationCode>CN VAT OUT 13</TaxClassificationCode><Country>中国</Country><FromDate>2022-10-14</FromDate><SourceSystem>SFA</SourceSystem><InvoiceName>测试20221014</InvoiceName></DATAINFO></DATAINFOS></DATA></ESB>";
        log.info("XmlString: " + xmlString.replace("\r\n", ""));
        log.info("XmlToJson: " + JsonToXmlTool.xmlToJson(xmlString).toJSONString());
        log.info("JsonToXml: " + JsonToXmlTool.jsonToXmlContainAttributes(JsonToXmlTool.xmlToJson(xmlString)));
        log.info("XmlString2: " + xmlString2);
        log.info("XmlToJson2: " + JsonToXmlTool.xmlToJson(xmlString2).toJSONString());
    }
}

4、效果

①、JsonToXml

{
  "ESB": {
    "DATA": {
      "DATAINFOS": {
        "PUUID": "",
        "DATAINFO": [
          {
            "Abbreviation": "深圳润园四季餐饮有限公司",
            "CityCode": "440300",
            "CooperationStatus": "合作中",
            "CATEGORYCODE": "00",
            "MULTICODE": {
              "VALUELIST": [
                {
                  "ContactMobile": "17365452345",
                  "IsPrimaryContact": "是",
                  "SfaContactId": "9173566440704169777",
                  "SPECIALITYCODE": "CONTACTINFO",
                  "LISTCODE": "VE244A9Y3FNUWN7K747KFU6H6L84RHI5",
                  "ContactEMail": "22133133@qq.com",
                  "ContactName": "李迪"
                },
                {
                  "ContactMobile": "17365459878",
                  "IsPrimaryContact": "否",
                  "SfaContactId": "6788874131617504418",
                  "SPECIALITYCODE": "CONTACTINFO",
                  "LISTCODE": "6WQB8MA09Z4776I430SJPC2TU6K93UU4",
                  "ContactEMail": "2233133@qq.com",
                  "ContactName": "吴繁荣"
                },
                {
                  "SiteContactName": "刘三",
                  "SiteAddress": "测试77777",
                  "SfaSiteId": "8480089929551622116",
                  "SPECIALITYCODE": "SITEINFO",
                  "SiteCityCode": "110000",
                  "LISTCODE": "WAHVUTQXQP7S0GQ36Z562W0S9OZ3QYEG",
                  "SiteContactMobile": "21878128337"
                }
              ]
            },
            "FILES": [
              {
                "STOREPATH": "6055786081413437802/cm/202210/ea56e72f4c2249ad8dc732517b36a634.jpg",
                "FILETYPE": "image/jpg"
              },
              {
                "STOREPATH": "6055786081413437802/cm/202301/59d94e4583cf42d2aa321694c8f5f483.jpg",
                "FILETYPE": "image/jpg"
              }
            ]
          }
        ]
      }
    }
  }
}
<ESB>
  <DATA>
    <DATAINFOS>
      <PUUID/>
      <DATAINFO>
        <Abbreviation>深圳润园四季餐饮有限公司</Abbreviation>
        <CityCode>440300</CityCode>
        <CooperationStatus>合作中</CooperationStatus>
        <CATEGORYCODE>00</CATEGORYCODE>
        <MULTICODE>
          <VALUELIST>
            <ContactMobile>17365452345</ContactMobile>
            <IsPrimaryContact>是</IsPrimaryContact>
            <SfaContactId>9173566440704169777</SfaContactId>
            <SPECIALITYCODE>CONTACTINFO</SPECIALITYCODE>
            <LISTCODE>VE244A9Y3FNUWN7K747KFU6H6L84RHI5</LISTCODE>
            <ContactEMail>22133133@qq.com</ContactEMail>
            <ContactName>李迪</ContactName>
          </VALUELIST>
          <VALUELIST>
            <ContactMobile>17365459878</ContactMobile>
            <IsPrimaryContact>否</IsPrimaryContact>
            <SfaContactId>6788874131617504418</SfaContactId>
            <SPECIALITYCODE>CONTACTINFO</SPECIALITYCODE>
            <LISTCODE>6WQB8MA09Z4776I430SJPC2TU6K93UU4</LISTCODE>
            <ContactEMail>2233133@qq.com</ContactEMail>
            <ContactName>吴繁荣</ContactName>
          </VALUELIST>
          <VALUELIST>
            <SiteContactName>刘三</SiteContactName>
            <SiteAddress>测试77777</SiteAddress>
            <SfaSiteId>8480089929551622116</SfaSiteId>
            <SPECIALITYCODE>SITEINFO</SPECIALITYCODE>
            <SiteCityCode>110000</SiteCityCode>
            <LISTCODE>WAHVUTQXQP7S0GQ36Z562W0S9OZ3QYEG</LISTCODE>
            <SiteContactMobile>21878128337</SiteContactMobile>
          </VALUELIST>
        </MULTICODE>
        <FILES>
          <STOREPATH>6055786081413437802/cm/202210/ea56e72f4c2249ad8dc732517b36a634.jpg</STOREPATH>
          <FILETYPE>image/jpg</FILETYPE>
        </FILES>
        <FILES>
          <STOREPATH>6055786081413437802/cm/202301/59d94e4583cf42d2aa321694c8f5f483.jpg</STOREPATH>
          <FILETYPE>image/jpg</FILETYPE>
        </FILES>
      </DATAINFO>
    </DATAINFOS>
  </DATA>
</ESB>

②、XmlToJson

<alexa ver="0.9" url="http://coursesweb.net/" home="0" aid="1"> 
  <sd title="a" host="coursesweb.net"> 
    <title>CoursesWeb: php, mysql, html, css, javascript, ajax, jquery, actionscript, flash</title>  
    <linksin/>  
    <speed pct="51">4578</speed> 
  </sd>  
  <sd> 
    <popularity>5777</popularity>  
    <reach rank="5952"/>  
    <rank url="http://coursesweb.net/">6667</rank> 
  </sd>  
  <child>5353543</child>
  <child test="hahahaha">子节点也没有子节点</child>
  <child test="2222">222子节点也没有子节点222</child>
</alexa>
{
  "alexa": {
    "@url": "http://coursesweb.net/",
    "sd": [
      {
        "@title": "a",
        "title": "CoursesWeb: php, mysql, html, css, javascript, ajax, jquery, actionscript, flash",
        "@host": "coursesweb.net",
        "speed": {
          "content": "4578",
          "@pct": "51"
        }
      },
      {
        "reach": {
          "@rank": "5952"
        },
        "popularity": "5777",
        "rank": {
          "@url": "http://coursesweb.net/",
          "content": "6667"
        }
      }
    ],
    "@aid": "1",
    "@home": "0",
    "@ver": "0.9",
    "child": [
      "5353543",
      {
        "@test": "hahahaha",
        "content": "子节点也没有子节点"
      },
      {
        "@test": "2222",
        "content": "222子节点也没有子节点222"
      }
    ]
  }
}


博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。