前言【
最近在寫一個業務,由於調UPS物流的接口返回的是一個xml格式的數據結果,我現在要拿到xml中某個節點的值,而這個xml數據是多節點多層級的,並且這某個節點的值有可能只有一條值,有可能有多條,如下:
大概是這樣的結構:為了簡要,我做簡單顯示,真正的結構層級跟這差不多
<class> <student> <name>aaaaaa</name> <girlfriend>bbb</girlfriend> <girlfriend>ccc</girlfriend> </student> </class>
>>>>由於girlfriend的值是不確定的,有可能一個,或多個>>>>
<class> <student> <name>aaaaaa</name> <girlfriend>bbb</girlfriend> </student> </class>
//現在要把當前xml轉成map,並且還要遍歷map,拿到girlfriend的值,於girlfriend的值有可能是多個
//所以當xml中的節點girlfriend的值不同時,我們都要解析成多層級的map,並拿到girlfriend的值
】
網上百度了很久,終於找到一位大神寫的一個xml轉map的工具,並且還附帶從map中查找某層級的子節點數據,借鑒博客:https://blog.csdn.net/lmb55/article/details/77507385
我在他的方法上做了一些小改動,因為我要根據classs>student>girlfriend拿到一個這樣{girlfriend=[bbb, ccc]},或{girlfriend=[bbb]},所以不管一個值還是多個值我都要放到map中的list中,但他的map取list數據方法只能取一到一個list值如[bbb, ccc]
好了,來解析一下:
第一步:把xml轉map方法:
/** * 將Element對象轉為Map(String→Document→Element→Map) * @param Element * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Map Dom2Map(Element e){ Map map = new HashMap(); List list = e.elements(); if(list.size() > 0){ for (int i = 0;i < list.size(); i++) { Element iter = (Element) list.get(i); List mapList = new ArrayList(); if(iter.elements().size() > 0){ Map m = Dom2Map(iter); if(map.get(iter.getName()) != null){ Object obj = map.get(iter.getName()); if(!obj.getClass().getName().equals("java.util.ArrayList")){ mapList = new ArrayList(); mapList.add(obj); mapList.add(m); } if(obj.getClass().getName().equals("java.util.ArrayList")){ mapList = (List) obj; mapList.add(m); } map.put(iter.getName(), mapList); }else map.put(iter.getName(), m); } else{ if(map.get(iter.getName()) != null){ Object obj = map.get(iter.getName()); if(!obj.getClass().getName().equals("java.util.ArrayList")){ mapList = new ArrayList(); mapList.add(obj); mapList.add(iter.getText()); } if(obj.getClass().getName().equals("java.util.ArrayList")){ mapList = (List) obj; mapList.add(iter.getText()); } map.put(iter.getName(), mapList); }else map.put(iter.getName(), iter.getText());//公共map resultCode=0 } } }else map.put(e.getName(), e.getText()); return map; }
//調用上面的xml轉map方法:
//xml轉map
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new ByteArrayInputStream(respXml.getBytes()));
Element incomingForm = document.getRootElement();
Map map = Dom2Map(incomingForm);
System.out.println("map >>> "+ map);
/*
* {resultMsg=成功, orderOffer={offer={offerSpecName=980010992)商務助手(OCS)30元, endDt=3000-1-1 0:00:00, startDt=2012-11-27 16:48:12, offerSpecId=980010992, params={param=[{offerParamId=101000048281, itemSpecName=計費區分, itemSpecId=5030, value=CDMA預付費}, {offerParamId=101000048282, itemSpecName=經分區分, itemSpecId=5031, value=天翼商話}]}, offerId=105000808918}}, resultCode=0, saleOffer={categoryNode={offer=[{summary=待定..., id=980001995, name=(980001995)商務助手(OCS)201209版-30元}, {summary=待定..., id=980001996, name=(980001996)商務助手(OCS)201209版-50元}, {summary=待定..., id=980001997, name=(980001997)商務助手(OCS)201209版-80元}, {summary=待定..., id=980010993, name=(980010993)商務助手(OCS)50元}]}}}
*/
第二步:xml已經轉成map數據結構了,下面要根據節點的層級路徑,拿到你想要的節點值
/** * 將多結點多層級的Map轉為多包體的list集合 * @param respStr * @param listNode * @return */ @SuppressWarnings("unchecked") public static Map<String, List<String>> map2ListbyHandler(Map respStr,String listNode){ List<String> resultList = new ArrayList<String>(); Map<String, List<String>> resultMap = new HashMap<>(); Map map = respStr; String[] strArray = listNode.split(">"); String key = null; Object value = null; for (int i = 0; i < strArray.length; i++) { if (map.get(strArray[i]) instanceof List) { if (i < strArray.length && null != map.get(strArray[i]) && "" != map.get(strArray[i])) { Map<String,Object> mapList = map; if (((List<Map<String,Object>>)mapList.get(strArray[i])).size() > 0) { // Map mapj = new HashMap(); // List<Map<String,Object>> list = ((List<Map<String,Object>>)mapList.get(strArray[i])); resultList = ((List<String>)mapList.get(strArray[i])); if(resultList.size() > 0){ resultMap.put(strArray[i], resultList); } return resultMap; } } break; }else{ if (i < strArray.length - 1 && null != map.get(strArray[i]) && "" != map.get(strArray[i])) { map = (Map) map.get(strArray[i]); }else{ //說明沒有此節點只有一個值,直接從map里把值取出放resultList中 resultList.add(map.get(strArray[i]).toString()); resultMap.put(strArray[i], resultList);//listNode } } } return resultMap; }
//調用上面的遍歷map取數據方法:原博客返回的是一個list,我給改成了map,因為我想要{girlfriend=[bbb, ccc]},或{girlfriend={bbb}}這種結果數據,方便我根據節點名稱取值
System.out.println("***************從map中將單個節點的值查找出來*********************");
//map轉list
Map resultMap = XmlToMapUtil01.map2ListbyHandler(map,"student>age"); System.out.println(resultMap.toString());
》》》》》》》》》》》》》》》》》》》》》》》》》》》》
好了,下面放上全部代碼,一個XmlToMapUtil01.java工具類代碼,和一個TestXmlToMap01.java用來測試工具類的文件
XmlToMapUtil01.java工具類
package com.saoptest.test03; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class XmlToMapUtil01 { /** * 將Document對象轉為Map(String→Document→Map) * @param Document * @return */ @SuppressWarnings("rawtypes") public static Map<String, Object> Dom2Map(Document doc){ Map<String, Object> map = new HashMap<String, Object>(); if(doc == null) return map; Element root = doc.getRootElement(); for (Iterator iterator = root.elementIterator(); iterator.hasNext();) { Element e = (Element) iterator.next(); //System.out.println(e.getName()); List list = e.elements(); if(list.size() > 0){ map.put(e.getName(), Dom2Map(e)); }else map.put(e.getName(), e.getText()); } return map; } /** * 將Element對象轉為Map(String→Document→Element→Map) * @param Element * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Map Dom2Map(Element e){ Map map = new HashMap(); List list = e.elements(); if(list.size() > 0){ for (int i = 0;i < list.size(); i++) { Element iter = (Element) list.get(i); List mapList = new ArrayList(); if(iter.elements().size() > 0){ Map m = Dom2Map(iter); if(map.get(iter.getName()) != null){ Object obj = map.get(iter.getName()); if(!obj.getClass().getName().equals("java.util.ArrayList")){ mapList = new ArrayList(); mapList.add(obj); mapList.add(m); } if(obj.getClass().getName().equals("java.util.ArrayList")){ mapList = (List) obj; mapList.add(m); } map.put(iter.getName(), mapList); }else map.put(iter.getName(), m); } else{ if(map.get(iter.getName()) != null){ Object obj = map.get(iter.getName()); if(!obj.getClass().getName().equals("java.util.ArrayList")){ mapList = new ArrayList(); mapList.add(obj); mapList.add(iter.getText()); } if(obj.getClass().getName().equals("java.util.ArrayList")){ mapList = (List) obj; mapList.add(iter.getText()); } map.put(iter.getName(), mapList); }else map.put(iter.getName(), iter.getText());//公共map resultCode=0 } } }else map.put(e.getName(), e.getText()); return map; } //=========================上面是單節點多層級的xml轉map==================================== //=========================下面是多節點多層級的xml轉map==================================== /** * 將多結點多層級的Map轉為多包體的list集合 * @param respStr * @param listNode * @return */ @SuppressWarnings("unchecked") public static Map<String, List<String>> map2ListbyHandler(Map respStr,String listNode){ List<String> resultList = new ArrayList<String>(); Map<String, List<String>> resultMap = new HashMap<>(); Map map = respStr; String[] strArray = listNode.split(">"); String key = null; Object value = null; for (int i = 0; i < strArray.length; i++) { if (map.get(strArray[i]) instanceof List) { if (i < strArray.length && null != map.get(strArray[i]) && "" != map.get(strArray[i])) { Map<String,Object> mapList = map; if (((List<Map<String,Object>>)mapList.get(strArray[i])).size() > 0) { // Map mapj = new HashMap(); // List<Map<String,Object>> list = ((List<Map<String,Object>>)mapList.get(strArray[i])); resultList = ((List<String>)mapList.get(strArray[i])); if(resultList.size() > 0){ resultMap.put(strArray[i], resultList); } return resultMap; } } break; }else{ if (i < strArray.length - 1 && null != map.get(strArray[i]) && "" != map.get(strArray[i])) { map = (Map) map.get(strArray[i]); }else{ //說明沒有此節點只有一個值,直接從map里把值取出放resultList中 resultList.add(map.get(strArray[i]).toString()); resultMap.put(strArray[i], resultList);//listNode } } } return resultMap; } //===============map測試========================== public static void main(String[] args) { StringBuffer sb = new StringBuffer(); sb.append("<response>"); sb.append(" <resultCode>0</resultCode>"); sb.append(" <resultMsg>成功</resultMsg>"); sb.append(" <orderOffer>"); sb.append(" <offer>"); sb.append(" <offerId>105000808918</offerId>"); sb.append(" <offerSpecId>980010992</offerSpecId>"); sb.append(" <offerSpecName>980010992)商務助手(OCS)30元</offerSpecName>"); sb.append(" <startDt>2012-11-27 16:48:12</startDt>"); sb.append(" <endDt>3000-1-1 0:00:00</endDt>"); sb.append(" <params>"); sb.append(" <param>"); sb.append(" <offerParamId>101000048281</offerParamId>"); sb.append(" <itemSpecId>5030</itemSpecId>"); sb.append(" <itemSpecName>計費區分</itemSpecName>"); sb.append(" <value>CDMA預付費</value>"); sb.append(" </param>"); sb.append(" <param>"); sb.append(" <offerParamId>101000048282</offerParamId>"); sb.append(" <itemSpecId>5031</itemSpecId>"); sb.append(" <itemSpecName>經分區分</itemSpecName>"); sb.append(" <value>天翼商話</value>"); sb.append(" </param>"); sb.append(" </params>"); sb.append(" </offer>"); sb.append(" </orderOffer>"); sb.append(" <saleOffer>"); sb.append(" <categoryNode id = \"100472\">"); sb.append(" <offer>"); sb.append(" <id>980001995</id>"); sb.append(" <name>(980001995)商務助手(OCS)201209版-30元</name>"); sb.append(" <summary>待定...</summary>"); sb.append(" </offer>"); sb.append(" <offer>"); sb.append(" <id>980001996</id>"); sb.append(" <name>(980001996)商務助手(OCS)201209版-50元</name>"); sb.append(" <summary>待定...</summary>"); sb.append(" </offer>"); sb.append(" <offer>"); sb.append(" <id>980001997</id>"); sb.append(" <name>(980001997)商務助手(OCS)201209版-80元</name>"); sb.append(" <summary>待定...</summary>"); sb.append(" </offer>"); sb.append(" <offer>"); sb.append(" <id>980010993</id>"); sb.append(" <name>(980010993)商務助手(OCS)50元</name>"); sb.append(" <summary>待定...</summary>"); sb.append(" </offer>"); sb.append(" </categoryNode>"); sb.append(" </saleOffer>"); sb.append("</response>"); String respXml = sb.toString(); try { //xml轉map SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new ByteArrayInputStream(respXml.getBytes())); Element incomingForm = document.getRootElement(); Map map = Dom2Map(incomingForm); System.out.println("map >>> "+ map); /* * {resultMsg=成功, orderOffer={offer={offerSpecName=980010992)商務助手(OCS)30元, endDt=3000-1-1 0:00:00, startDt=2012-11-27 16:48:12, offerSpecId=980010992, params={param=[{offerParamId=101000048281, itemSpecName=計費區分, itemSpecId=5030, value=CDMA預付費}, {offerParamId=101000048282, itemSpecName=經分區分, itemSpecId=5031, value=天翼商話}]}, offerId=105000808918}}, resultCode=0, saleOffer={categoryNode={offer=[{summary=待定..., id=980001995, name=(980001995)商務助手(OCS)201209版-30元}, {summary=待定..., id=980001996, name=(980001996)商務助手(OCS)201209版-50元}, {summary=待定..., id=980001997, name=(980001997)商務助手(OCS)201209版-80元}, {summary=待定..., id=980010993, name=(980010993)商務助手(OCS)50元}]}}} */ System.out.println("***************從map中將單個節點的值查找出來*********************"); //map轉list map2ListbyHandler(map,"saleOffer>categoryNode>offer>id"); /* * resultList >>> [{id=980001995}, {id=980001996}, {id=980001997}, {id=980010993}] */ System.out.println("***************從map中將節點集合中的所有節點值都查找出來*******************************"); List<String> nodeList = new ArrayList<String>(); nodeList.add("resultCode"); nodeList.add("resultMsg"); nodeList.add("orderOffer>offer>offerSpecName"); nodeList.add("orderOffer>offer>endDt"); nodeList.add("orderOffer>offer>startDt"); nodeList.add("orderOffer>offer>offerSpecId"); nodeList.add("orderOffer>offer>offerId"); nodeList.add("orderOffer>offer>params>param>offerParamId"); nodeList.add("orderOffer>offer>params>param>itemSpecName"); nodeList.add("orderOffer>offer>params>param>itemSpecId"); nodeList.add("orderOffer>offer>params>param>value"); nodeList.add("saleOffer>categoryNode>offer>id"); nodeList.add("saleOffer>categoryNode>offer>summary"); nodeList.add("saleOffer>categoryNode>offer>name"); // str2ListbyHandler(nodeList,respXml); /** * [{offerParamId=101000048281, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001995, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048282, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001995, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048281, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001996, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048282, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001996, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048281, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001997, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048282, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980001997, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048281, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980010993, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}, * {offerParamId=101000048282, summary=待定..., endDt=3000-1-1 0:00:00, itemSpecId=5031, id=980010993, resultMsg=成功, * itemSpecName=經分區分, offerSpecName=980010992)商務助手(OCS)30元, offerSpecId=980010992, startDt=2012-11-27 16:48:12, * name=(980010993)商務助手(OCS)50元, resultCode=0, value=天翼商話, offerId=105000808918}] */ } catch (DocumentException e) { e.printStackTrace(); } } }
TestXmlToMap01.java
package com.saoptest.test03; import java.io.ByteArrayInputStream; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class TestXmlToMap01 { public static void main(String[] args) throws Exception { //xml轉json String xml = "<class><student><name>aaaaaa</name><girlfriend>bbb</girlfriend><girlfriend>ccc</girlfriend></student></class>"; // String xml = "<class><student><name>aaaaaa</name><girlfriend>bbb</girlfriend></student></class>"; // String xml = "<class><student><name>aaaaaa</name><age>21</age></student><student><name>bbbbbb</name><age>22</age></student></class>"; // String xml = "<class><student><name>aaaaaa</name><age>21</age></student></class>"; //xml轉map SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new ByteArrayInputStream(xml.getBytes())); Element incomingForm = document.getRootElement(); Map map = XmlToMapUtil01.Dom2Map(incomingForm); System.out.println("map >>> "+ map); /* * {resultMsg=成功, orderOffer={offer={offerSpecName=980010992)商務助手(OCS)30元, endDt=3000-1-1 0:00:00, startDt=2012-11-27 16:48:12, offerSpecId=980010992, params={param=[{offerParamId=101000048281, itemSpecName=計費區分, itemSpecId=5030, value=CDMA預付費}, {offerParamId=101000048282, itemSpecName=經分區分, itemSpecId=5031, value=天翼商話}]}, offerId=105000808918}}, resultCode=0, saleOffer={categoryNode={offer=[{summary=待定..., id=980001995, name=(980001995)商務助手(OCS)201209版-30元}, {summary=待定..., id=980001996, name=(980001996)商務助手(OCS)201209版-50元}, {summary=待定..., id=980001997, name=(980001997)商務助手(OCS)201209版-80元}, {summary=待定..., id=980010993, name=(980010993)商務助手(OCS)50元}]}}} */ System.out.println("***************從map中將單個節點的值查找出來*********************"); //map轉list Map<String, List<String>> resultMap = XmlToMapUtil01.map2ListbyHandler(map,"student>girlfriend"); List<String> list = resultMap.get("girlfriend"); System.out.println("resultMap=" + resultMap.toString()); if(!"null".equals(resultMap.get("girlfriend").toString())){ System.out.println("有數據:" + resultMap.get("girlfriend")); }else{ System.out.println("沒數據:" + resultMap.get("girlfriend")); } // Map<String, List<String>> map1 = new HashMap<String, List<String>>(); // List<String> lists = new ArrayList<String>(); // lists.add("bbb"); // lists.add("ccc"); // map1.put("girlfriend", lists); // System.out.println("map1====" + map1.toString()); // System.out.println(map1.get("girlfriend")); // System.out.println(map1.get("girlfriend").get(0) + "=====" + map1.get("girlfriend").get(1)); // } }