Java读取多层级xml文件

       最近在做国际客服北京职场的项目,需要提供一个接口服务端的能力,也就是需要开发一个http+xml的协议,入参和出参均为Map格式,各系统间的请求或应答是以xml格式封装的。在将返回报文(xml)解析为Map输出时遇到一个难点:Java对于多层级xml的解析。现以一个客户资料查询接口为例将解析过程记录如下:

返回xml报文的简化形式:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <ROOT>  
  3.       <HEAD>  
  4.             <ORIGIN_DOMAIN>kefuxitongbianma</ORIGIN_DOMAIN>  
  5.             <HOME_DOMAIN>CUGCRM</HOME_DOMAIN>  
  6.             <ACTION_CODE>1</ACTION_CODE>  
  7.             <BUSI_CODE>QUERYCUST</BUSI_CODE>  
  8.             <TRANS_ID>20160220160635123456</TRANS_ID>  
  9.             <RET_CODE>0000</RET_CODE>  
  10.             <RET_MSG>success</RET_MSG>  
  11.       </HEAD>  
  12.       <BODY>  
  13.             <TOTAL_RECORDS>20</TOTAL_RECORDS>  
  14.             <TOTAL_PAGE>10</TOTAL_PAGE>  
  15.             <CURRENT_PAGE>1</CURRENT_PAGE>  
  16.             <CUSTINFOLIST>  
  17.                   <CUSTINFO>  
  18.                         <CUST_TYPE>001</CUST_TYPE>  
  19.                         <VIP_FLAG>true</VIP_FLAG>  
  20.                   </CUSTINFO>  
  21.                   <CUSTINFO>  
  22.                         <CUST_TYPE>002</CUST_TYPE>  
  23.                         <VIP_FLAG>false</VIP_FLAG>  
  24.                   </CUSTINFO>  
  25.                   <CUSTINFO>  
  26.                         <CUST_TYPE>003</CUST_TYPE>  
  27.                         <VIP_FLAG>false</VIP_FLAG>  
  28.                   </CUSTINFO>  
  29.             </CUSTINFOLIST>  
  30.       </BODY>  
  31. </ROOT>  

[java]  view plain  copy
  1. import java.util.ArrayList;  
  2. import java.util.HashMap;  
  3. import java.util.List;  
  4. import java.util.Map;  
  5. import java.util.Set;  
  6. import net.sf.json.JSONObject;  
  7. import org.apache.log4j.Logger;  
  8. import org.dom4j.Document;  
  9. import org.dom4j.DocumentException;  
  10. import org.dom4j.DocumentHelper;  
  11. import org.dom4j.Element;  
  12. import org.dom4j.Namespace;  
  13. import org.dom4j.QName;  
  14. /** 
  15.  * 解析xml的工具类 
  16.  * 1、将多层级xml解析为Map 
  17.  * 2、将多层级xml解析为Json 
  18.  * 
  19.  * @author lmb 
  20.  * 
  21.  */  
  22. public class ParseXmlUtil {  
  23.         
  24.       public static Logger logger = Logger.getLogger(ParseXmlUtil.class);  
  25.       public static void main(String[] args) {   
  26.               // 获取一个xml文件   
  27.               String textFromFile = MyXmlUtil.XmlToString();  
  28.               //将xml解析为Map  
  29.               Map resultMap = xml2map(textFromFile);  
  30.               //将xml解析为Json  
  31.               String resultJson = xml2Json(textFromFile);  
  32.       }   
  33.         
  34.         
  35.       /** 
  36.        * 将xml格式响应报文解析为Json格式 
  37.        * @param responseXmlTemp 
  38.        * @return 
  39.        */  
  40.       public static String xml2Json(String responseXmlTemp) {  
  41.             Document doc = null;  
  42.             try {  
  43.                   doc = DocumentHelper.parseText(responseXmlTemp);  
  44.             } catch (DocumentException e) {  
  45.                   logger.error("parse text error : " + e);  
  46.             }  
  47.             Element rootElement = doc.getRootElement();  
  48.             Map<String,Object> mapXml = new HashMap<String,Object>();  
  49.             element2Map(mapXml,rootElement);  
  50.             String jsonXml = JSONObject.fromObject(mapXml).toString();  
  51.             System.out.println("Json >>> " + jsonXml);  
  52.             return jsonXml;  
  53.       }  
  54.       /** 
  55.        * 将xml格式响应报文解析为Map格式 
  56.        * @param responseXmlTemp 
  57.        * @param thirdXmlServiceBean 
  58.        * @return 
  59.        * @throws DocumentException 
  60.        */  
  61.       public static Map<String, Object> xml2map(String responseXmlTemp) {  
  62.             Document doc = null;  
  63.             try {  
  64.                   doc = DocumentHelper.parseText(responseXmlTemp);  
  65.             } catch (DocumentException e) {  
  66.                   logger.error("parse text error : " + e);  
  67.             }  
  68.             Element rootElement = doc.getRootElement();  
  69.             Map<String,Object> mapXml = new HashMap<String,Object>();  
  70.             element2Map(mapXml,rootElement);  
  71.             System.out.println("Map >>> " + mapXml);  
  72.             return mapXml;  
  73.       }  
  74.       /** 
  75.        * 使用递归调用将多层级xml转为map 
  76.        * @param map 
  77.        * @param rootElement 
  78.        */  
  79.       public static void element2Map(Map<String, Object> map, Element rootElement) {  
  80.               
  81.             //获得当前节点的子节点  
  82.             List<Element> elements = rootElement.elements();  
  83.             if (elements.size() == 0) {  
  84.                   //没有子节点说明当前节点是叶子节点,直接取值  
  85.                   map.put(rootElement.getName(),rootElement.getText());  
  86.             }else if (elements.size() == 1) {  
  87.                   //只有一个子节点说明不用考虑list的情况,继续递归  
  88.                   Map<String,Object> tempMap = new HashMap<String,Object>();  
  89.                   element2Map(tempMap,elements.get(0));  
  90.                   map.put(rootElement.getName(),tempMap);  
  91.             }else {  
  92.                   //多个子节点的话就要考虑list的情况了,特别是当多个子节点有名称相同的字段时  
  93.                   Map<String,Object> tempMap = new HashMap<String,Object>();  
  94.                   for (Element element : elements) {  
  95.                         tempMap.put(element.getName(),null);  
  96.                   }  
  97.                   Set<String> keySet = tempMap.keySet();  
  98.                   for (String string : keySet) {  
  99.                         Namespace namespace = elements.get(0).getNamespace();  
  100.                         List<Element> sameElements = rootElement.elements(new QName(string,namespace));  
  101.                         //如果同名的数目大于1则表示要构建list  
  102.                         if (sameElements.size() > 1) {  
  103.                               List<Map> list = new ArrayList<Map>();  
  104.                               for(Element element : sameElements){  
  105.                                     Map<String,Object> sameTempMap = new HashMap<String,Object>();  
  106.                                     element2Map(sameTempMap,element);  
  107.                                     list.add(sameTempMap);  
  108.                               }  
  109.                               map.put(string,list);  
  110.                         }else {  
  111.                               //同名的数量不大于1直接递归  
  112.                               Map<String,Object> sameTempMap = new HashMap<String,Object>();  
  113.                               element2Map(sameTempMap,sameElements.get(0));  
  114.                               map.put(string,sameTempMap);  
  115.                         }  
  116.                   }  
  117.             }  
  118.       }  
  119. }  

xml文件读取工具类:

[java]  view plain  copy
  1. import java.io.File;  
  2. import java.io.IOException;  
  3. import java.io.StringWriter;  
  4. import org.jdom.Document;  
  5. import org.jdom.input.SAXBuilder;  
  6. import org.jdom.output.Format;  
  7. import org.jdom.output.XMLOutputter;  
  8. /** 
  9.  * 读取一个xml文件返回string 
  10.  * @author lmb  
  11.  * 
  12.  */  
  13. public class MyXmlUtil {  
  14.       /** 
  15.        * 加载xml文件 
  16.        * @return Document 
  17.        */  
  18.       public static Document load(){  
  19.             Document document=null;   
  20.         String url="E://2.xml";   
  21.         try {   
  22.             SAXBuilder reader = new SAXBuilder();    
  23.             document=reader.build(new File(url));   
  24.        } catch (Exception e) {   
  25.             e.printStackTrace();   
  26.        }   
  27.         return document;  
  28.       }  
  29.         
  30.       /** 
  31.        * 将xml文件转换为String串 
  32.        * @return 
  33.        */  
  34.       public static String XmlToString(){  
  35.             Document document=null;   
  36.         document=load();   
  37.            
  38.         Format format =Format.getPrettyFormat();       
  39.         format.setEncoding("UTF-8");//设置编码格式    
  40.            
  41.         StringWriter out=null//输出对象   
  42.         String sReturn =""//输出字符串   
  43.         XMLOutputter outputter =new XMLOutputter();    
  44.         out=new StringWriter();    
  45.         try {   
  46.            outputter.output(document,out);   
  47.         } catch (IOException e) {   
  48.            e.printStackTrace();   
  49.         }    
  50.         sReturn=out.toString();    
  51.         return sReturn;   
  52.     }   
  53. }  

控制台打印结果:

[html]  view plain  copy
  1. 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}}}  
  2.   
  3. 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"}}}  

格式化之后的结果如下:

[html]  view plain  copy
  1. <strong>map :</strong>  
  2. {  
  3.     BODY={  
  4.         TOTAL_RECORDS={TOTAL_RECORDS=20},  
  5.         CUSTINFOLIST={  
  6.             CUSTINFO=[  
  7.                 {  
  8.                     CUST_TYPE={CUST_TYPE=001},  
  9.                     VIP_FLAG={VIP_FLAG=true}  
  10.                 },  
  11.                 {  
  12.                     CUST_TYPE={CUST_TYPE=002},  
  13.                     VIP_FLAG={VIP_FLAG=false}  
  14.                 },  
  15.                 {  
  16.                     CUST_TYPE={CUST_TYPE=003},  
  17.                     VIP_FLAG={VIP_FLAG=false}  
  18.                 }  
  19.             ]  
  20.         },  
  21.         TOTAL_PAGE={TOTAL_PAGE=10},  
  22.         CURRENT_PAGE={CURRENT_PAGE=1}  
  23.     },  
  24.     HEAD={  
  25.         ACTION_CODE={ACTION_CODE=1},  
  26.         ORIGIN_DOMAIN={ORIGIN_DOMAIN=kefuxit},  
  27.         BUSI_CODE={BUSI_CODE=QUERYCUST},  
  28.         HOME_DOMAIN={HOME_DOMAIN=CUGCRM},  
  29.         TRANS_ID={TRANS_ID=20160220160635123456},  
  30.         RET_MSG={RET_MSG=success},  
  31.         RET_CODE={RET_CODE=0000}  
  32.     }  
  33. }  
  34.   
  35. <strong>Json:</strong>  
  36. {  
  37.     "BODY":{  
  38.         "TOTAL_RECORDS":{"TOTAL_RECORDS":"20"},  
  39.         "CUSTINFOLIST":{  
  40.             "CUSTINFO":[  
  41.                 {  
  42.                     "CUST_TYPE":{"CUST_TYPE":"001"},  
  43.                     "VIP_FLAG":{"VIP_FLAG":"true"}  
  44.                 },  
  45.                 {  
  46.                     "CUST_TYPE":{"CUST_TYPE":"002"},  
  47.                     "VIP_FLAG":{"VIP_FLAG":"false"}  
  48.                 },  
  49.                 {  
  50.                     "CUST_TYPE":{"CUST_TYPE":"003"},  
  51.                     "VIP_FLAG":{"VIP_FLAG":"false"}  
  52.                 }  
  53.             ]  
  54.         },  
  55.         "TOTAL_PAGE":{"TOTAL_PAGE":"10"},  
  56.         "CURRENT_PAGE":{"CURRENT_PAGE":"1"}  
  57.     },  
  58.     "HEAD":{  
  59.         "ACTION_CODE":{"ACTION_CODE":"1"},  
  60.         "ORIGIN_DOMAIN":{"ORIGIN_DOMAIN":"kefuxit"},  
  61.         "BUSI_CODE":{"BUSI_CODE":"QUERYCUST"},  
  62.         "HOME_DOMAIN":{"HOME_DOMAIN":"CUGCRM"},  
  63.         "TRANS_ID":{"TRANS_ID":"20160220160635123456"},  
  64.         "RET_MSG":{"RET_MSG":"success"},  
  65.         "RET_CODE":{"RET_CODE":"0000"}  
  66.     }  

猜你喜欢

转载自blog.csdn.net/u010598111/article/details/78315571
今日推荐