最近在做国际客服北京职场的项目,需要提供一个接口服务端的能力,也就是需要开发一个http+xml的协议,入参和出参均为Map格式,各系统间的请求或应答是以xml格式封装的。在将返回报文(xml)解析为Map输出时遇到一个难点:Java对于多层级xml的解析。现以一个客户资料查询接口为例将解析过程记录如下:
返回xml报文的简化形式:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT><HEAD><ORIGIN_DOMAIN>kefuxitongbianma</ORIGIN_DOMAIN><HOME_DOMAIN>CUGCRM</HOME_DOMAIN><ACTION_CODE>1</ACTION_CODE><BUSI_CODE>QUERYCUST</BUSI_CODE><TRANS_ID>20160220160635123456</TRANS_ID><RET_CODE>0000</RET_CODE><RET_MSG>success</RET_MSG></HEAD><BODY><TOTAL_RECORDS>20</TOTAL_RECORDS><TOTAL_PAGE>10</TOTAL_PAGE><CURRENT_PAGE>1</CURRENT_PAGE><CUSTINFOLIST><CUSTINFO><CUST_TYPE>001</CUST_TYPE><VIP_FLAG>true</VIP_FLAG></CUSTINFO><CUSTINFO><CUST_TYPE>002</CUST_TYPE><VIP_FLAG>false</VIP_FLAG></CUSTINFO><CUSTINFO><CUST_TYPE>003</CUST_TYPE><VIP_FLAG>false</VIP_FLAG></CUSTINFO></CUSTINFOLIST></BODY>
</ROOT>
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
/*** 解析xml的工具类* 1、将多层级xml解析为Map* 2、将多层级xml解析为Json** @author lmb**/
public class ParseXmlUtil {public static Logger logger = Logger.getLogger(ParseXmlUtil.class);public static void main(String[] args) { // 获取一个xml文件 String textFromFile = MyXmlUtil.XmlToString();//将xml解析为MapMap resultMap = xml2map(textFromFile);//将xml解析为JsonString resultJson = xml2Json(textFromFile);} /*** 将xml格式响应报文解析为Json格式* @param responseXmlTemp* @return*/public static String xml2Json(String responseXmlTemp) {Document doc = null;try {doc = DocumentHelper.parseText(responseXmlTemp);} catch (DocumentException e) {logger.error("parse text error : " + e);}Element rootElement = doc.getRootElement();Map<String,Object> mapXml = new HashMap<String,Object>();element2Map(mapXml,rootElement);String jsonXml = JSONObject.fromObject(mapXml).toString();System.out.println("Json >>> " + jsonXml);return jsonXml;}/*** 将xml格式响应报文解析为Map格式* @param responseXmlTemp* @param thirdXmlServiceBean* @return* @throws DocumentException*/public static Map<String, Object> xml2map(String responseXmlTemp) {Document doc = null;try {doc = DocumentHelper.parseText(responseXmlTemp);} catch (DocumentException e) {logger.error("parse text error : " + e);}Element rootElement = doc.getRootElement();Map<String,Object> mapXml = new HashMap<String,Object>();element2Map(mapXml,rootElement);System.out.println("Map >>> " + mapXml);return mapXml;}/*** 使用递归调用将多层级xml转为map* @param map* @param rootElement*/public static void element2Map(Map<String, Object> map, Element rootElement) {//获得当前节点的子节点List<Element> elements = rootElement.elements();if (elements.size() == 0) {//没有子节点说明当前节点是叶子节点,直接取值map.put(rootElement.getName(),rootElement.getText());}else if (elements.size() == 1) {//只有一个子节点说明不用考虑list的情况,继续递归Map<String,Object> tempMap = new HashMap<String,Object>();element2Map(tempMap,elements.get(0));map.put(rootElement.getName(),tempMap);}else {//多个子节点的话就要考虑list的情况了,特别是当多个子节点有名称相同的字段时Map<String,Object> tempMap = new HashMap<String,Object>();for (Element element : elements) {tempMap.put(element.getName(),null);}Set<String> keySet = tempMap.keySet();for (String string : keySet) {Namespace namespace = elements.get(0).getNamespace();List<Element> sameElements = rootElement.elements(new QName(string,namespace));//如果同名的数目大于1则表示要构建listif (sameElements.size() > 1) {List<Map> list = new ArrayList<Map>();for(Element element : sameElements){Map<String,Object> sameTempMap = new HashMap<String,Object>();element2Map(sameTempMap,element);list.add(sameTempMap);}map.put(string,list);}else {//同名的数量不大于1直接递归Map<String,Object> sameTempMap = new HashMap<String,Object>();element2Map(sameTempMap,sameElements.get(0));map.put(string,sameTempMap);}}}}
}

xml文件读取工具类:

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
/*** 读取一个xml文件返回string* @author lmb **/
public class MyXmlUtil {/*** 加载xml文件* @return Document*/public static Document load(){Document document=null; String url="E://2.xml"; try { SAXBuilder reader = new SAXBuilder();  document=reader.build(new File(url)); } catch (Exception e) { e.printStackTrace(); } return document;}/*** 将xml文件转换为String串* @return*/public static String XmlToString(){Document document=null; document=load(); Format format =Format.getPrettyFormat();     format.setEncoding("UTF-8");//设置编码格式  StringWriter out=null; //输出对象 String sReturn =""; //输出字符串 XMLOutputter outputter =new XMLOutputter();  out=new StringWriter();  try { outputter.output(document,out); } catch (IOException e) { e.printStackTrace(); }  sReturn=out.toString();  return sReturn; }
}

控制台打印结果:

Map >>> {BODY={TOTAL_RECORDS={TOTAL_RECORDS=20}, CUSTINFOLIST={CUSTINFO=[{CUST_TYPE={CUST_TYPE=001}, VIP_FLAG={VIP_FLAG=true}}, {CUST_TYPE={CUST_TYPE=002}, VIP_FLAG={VIP_FLAG=false}}, {CUST_TYPE={CUST_TYPE=003}, VIP_FLAG={VIP_FLAG=false}}]}, TOTAL_PAGE={TOTAL_PAGE=10}, CURRENT_PAGE={CURRENT_PAGE=1}}, HEAD={ACTION_CODE={ACTION_CODE=1}, ORIGIN_DOMAIN={ORIGIN_DOMAIN=kefuxit}, BUSI_CODE={BUSI_CODE=QUERYCUST}, HOME_DOMAIN={HOME_DOMAIN=CUGCRM}, TRANS_ID={TRANS_ID=20160220160635123456}, RET_MSG={RET_MSG=success}, RET_CODE={RET_CODE=0000}}}Json >>> {"BODY":{"TOTAL_RECORDS":{"TOTAL_RECORDS":"20"},"CUSTINFOLIST":{"CUSTINFO":[{"CUST_TYPE":{"CUST_TYPE":"001"},"VIP_FLAG":{"VIP_FLAG":"true"}},{"CUST_TYPE":{"CUST_TYPE":"002"},"VIP_FLAG":{"VIP_FLAG":"false"}},{"CUST_TYPE":{"CUST_TYPE":"003"},"VIP_FLAG":{"VIP_FLAG":"false"}}]},"TOTAL_PAGE":{"TOTAL_PAGE":"10"},"CURRENT_PAGE":{"CURRENT_PAGE":"1"}},"HEAD":{"ACTION_CODE":{"ACTION_CODE":"1"},"ORIGIN_DOMAIN":{"ORIGIN_DOMAIN":"kefuxit"},"BUSI_CODE":{"BUSI_CODE":"QUERYCUST"},"HOME_DOMAIN":{"HOME_DOMAIN":"CUGCRM"},"TRANS_ID":{"TRANS_ID":"20160220160635123456"},"RET_MSG":{"RET_MSG":"success"},"RET_CODE":{"RET_CODE":"0000"}}}

格式化之后的结果如下:

map :
{BODY={TOTAL_RECORDS={TOTAL_RECORDS=20},CUSTINFOLIST={CUSTINFO=[{CUST_TYPE={CUST_TYPE=001},VIP_FLAG={VIP_FLAG=true}},{CUST_TYPE={CUST_TYPE=002},VIP_FLAG={VIP_FLAG=false}},{CUST_TYPE={CUST_TYPE=003},VIP_FLAG={VIP_FLAG=false}}]},TOTAL_PAGE={TOTAL_PAGE=10},CURRENT_PAGE={CURRENT_PAGE=1}},HEAD={ACTION_CODE={ACTION_CODE=1},ORIGIN_DOMAIN={ORIGIN_DOMAIN=kefuxit},BUSI_CODE={BUSI_CODE=QUERYCUST},HOME_DOMAIN={HOME_DOMAIN=CUGCRM},TRANS_ID={TRANS_ID=20160220160635123456},RET_MSG={RET_MSG=success},RET_CODE={RET_CODE=0000}}
}Json:
{"BODY":{"TOTAL_RECORDS":{"TOTAL_RECORDS":"20"},"CUSTINFOLIST":{"CUSTINFO":[{"CUST_TYPE":{"CUST_TYPE":"001"},"VIP_FLAG":{"VIP_FLAG":"true"}},{"CUST_TYPE":{"CUST_TYPE":"002"},"VIP_FLAG":{"VIP_FLAG":"false"}},{"CUST_TYPE":{"CUST_TYPE":"003"},"VIP_FLAG":{"VIP_FLAG":"false"}}]},"TOTAL_PAGE":{"TOTAL_PAGE":"10"},"CURRENT_PAGE":{"CURRENT_PAGE":"1"}},"HEAD":{"ACTION_CODE":{"ACTION_CODE":"1"},"ORIGIN_DOMAIN":{"ORIGIN_DOMAIN":"kefuxit"},"BUSI_CODE":{"BUSI_CODE":"QUERYCUST"},"HOME_DOMAIN":{"HOME_DOMAIN":"CUGCRM"},"TRANS_ID":{"TRANS_ID":"20160220160635123456"},"RET_MSG":{"RET_MSG":"success"},"RET_CODE":{"RET_CODE":"0000"}}
}

Java读取多层级xml文件相关推荐

  1. java读取并修改xml文件

    java读取并修改xml文件 java如何读取xml并且修改xml文件呢?代码如下: //复制模板xnl File file = new File(xmlSavePath + "/mb.xm ...

  2. java dom创建xml文件_Java 如何使用dom方式读取和创建xml文件

    Java 如何使用dom方式读取和创建xml文件 发布时间:2020-11-11 17:08:31 来源:亿速云 阅读:101 作者:Leah 本篇文章给大家分享的是有关Java 如何使用dom方式读 ...

  3. Java读取Level-1行情dbf文件极致优化(2)

    最近架构一个项目,实现行情的接入和分发,需要达到极致的低时延特性,这对于证券系统是非常重要的.接入的行情源是可以配置,既可以是Level-1,也可以是Level-2或其他第三方的源.虽然Level-1 ...

  4. jq ajax xml,jQuery+ajax读取并解析XML文件的方法

    本文实例讲述了jQuery+ajax读取并解析XML文件的方法.分享给大家供大家参考,具体如下: ajax.xml: zhangsan 1 lisi 2 demo.html: /p> " ...

  5. java读取各类型的文件

    java读取各类型的文件 用到的几个包 bcmail-jdk14-132.jar/bcprov-jdk14-132.jar/checkstyle-all-4.2.jar/FontBox-0.1.0-d ...

  6. Java读取UTF-8格式txt文件第一行出现乱码及解决;Java读带有BOM的UTF-8文件乱码原因及解决方法(转载)...

    原文地址:http://blog.csdn.net/jackpk/article/details/5702964/ Java读取UTF-8的txt文件第一行出现乱码"?"及解决 t ...

  7. JAVA增删改查XML文件

    2019独角兽企业重金招聘Python工程师标准>>> 最近总是需要进行xml的相关操作. 不免的要进行xml的读取修改等,于是上网搜索,加上自己的小改动,整合了下xml的常用操作. ...

  8. Java读取、创建xml(通过dom方式)

    创建一个接口 XmlInterface.java public interface XmlInterface {/** * 建立XML文档 * @param fileName 文件全路径名称 */ p ...

  9. Java Web的web.xml文件作用及基本配置(转)

    其实web.xml就是asp.net的web.config一个道理. 说明: 一个web中完全可以没有web.xml文件,也就是说,web.xml文件并不是web工程必须的. web.xml文件是用来 ...

最新文章

  1. 用户变量和系统变量的区别
  2. MacBook(m1)配置Python注意事项(自用,持续更新)
  3. UA OPTI570 量子力学24 Spin-1/2
  4. pLSA概率潜在语义分析
  5. ppt科研绘图 图形布尔运算
  6. PHP判断客户端的浏览器类型
  7. 信息学奥赛一本通 1063:最大跨度值 | OpenJudge NOI 1.5 06:整数序列的元素最大跨度值
  8. OpenJDK-11的新特征
  9. 业务中台建设与应用_中心牵头建设公司数据中台数据标签库和客户关系图谱库试点应用正式上线...
  10. QPushButton的四个信号:pressed(),clicked(),released(),toggled()
  11. 【POJ2318】TOYS(点在凸多边形内判定---模版暴力/二分)
  12. 传智播客-刘意-java深入浅出精华版学习笔记Day03
  13. xshell修改字体大小
  14. 太阳能发电板的规格尺寸_太阳能电池板瓦数和尺寸如何计算?
  15. facebook登陆ios
  16. 关于日程权限、黄历App功能使用流程
  17. win10-未知的USB设备-解决自己问题的记录
  18. python虚拟数字人直播间带货
  19. 5款好用的mysql客户端
  20. 100个Python实战练手项目(附源码+素材),学习必备

热门文章

  1. 安卓开发环境搭建(转)
  2. SQL_server_2000安装过程指导
  3. 【Node】模块加载过程
  4. define 解析依赖,判断状态,初始化/触发加载 --------require 同步加载(直接返回)/异步加载(创建匿名模块,判断状态,初始化/触发加载)
  5. WebApp本地存储 (离线缓存策略策略)
  6. Android Bundle--ArrayMap详解
  7. 深度学习端上部署工具
  8. SpringBoot—启动原理
  9. ListView和GridView的缓存机制及measure过程
  10. 解决Picasso在Android 5.0以下版本不兼容https导致图片不显示