1. 程式人生 > >xml 轉換 map (包括屬性和相同元素處理)

xml 轉換 map (包括屬性和相同元素處理)

xml轉map,從網上看了一些部落格,都不能完全滿足需求,自己在其他部落格分享的方法上進一步處理,最終滿足所有格式xml轉map。
在這裡感謝這些博主分享文章。(具體使用了哪位博主的文章有點記不清楚了)
直接看程式碼:

package com.test.parsedata

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import
org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.springframework.util.StringUtils; /** * 解析xml資料 * * @author commuli * @date 2017年8月27日 */ public class ParseXml implements IParseData { @Override public
List<Map<String, Object>> parseData(String str, Object obj) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); Document doc = null; try { // 轉為可解析物件 doc = DocumentHelper.parseText(str); } catch (DocumentException e) { e.
printStackTrace(); } Map<String, Object> map = new HashMap<String, Object>(); if (doc == null) return list; // 獲取根節點 Element rootElement = doc.getRootElement(); // 轉換map element2map(rootElement, map); list.add(map); return list; } @Override public List<Map<String, Object>> parseData(InputStream in, Object obj) { return parseData(in, "utf-8", null); } @Override public List<Map<String, Object>> parseData(InputStream in, String charsetName, Object obj) { String str = IOUtil.getString(in, charsetName); if (!StringUtils.isEmpty(str)) { return parseData(str, obj); } return null; } /** * xml元素轉map * * @param elmt * @param map */ private void element2map(Element elmt, Map<String, Object> map) { if (null == elmt) { return; } String name = elmt.getName(); // 當前元素是最小元素 if (elmt.isTextOnly()) { // 檢視map中是否已經有當前節點 Object f = map.get(name); // 用於存放元素屬性 Map<String, Object> m = new HashMap<String, Object>(); // 遍歷元素中的屬性 Iterator ai = elmt.attributeIterator(); // 用於第一次獲取該元素資料 boolean aiHasNex = false; while (ai.hasNext()) { aiHasNex = true; // 拿到屬性值 Attribute next = (Attribute) ai.next(); m.put(name + "." + next.getName(), next.getValue()); } // 第一次獲取該元素 if (f == null) { // 判斷如果有屬性 if (aiHasNex) { // 將屬性map存入解析map中 m.put(name, elmt.getText()); map.put(name, m); } else { // 沒有屬性,直接存入相應的值 map.put(name, elmt.getText()); } } else { // 解析map中已經有相同的節點 // 如果當前值是list if (f instanceof List<?>) { // list中新增此元素 m.put(name, elmt.getText()); ((List) f).add(m); } else { // 如果不是,說明解析map中只存在一個與此元素名相同的物件 // 存放元素 List<Object> listSub = new ArrayList<Object>(); // 如果解析map中的值為string,說明第一個元素沒有屬性 if (f instanceof String) { // 轉換為map物件, Map<String, Object> m1 = new HashMap<String, Object>(); m1.put(name, f); // 新增到list中 listSub.add(m1); } else { // 否則直接新增值 listSub.add(f); } // 將當前的值包含的屬性值放入list中 m.put(name, elmt.getText()); listSub.add(m); // 解析map中存入list map.put(name, listSub); } } } else { // 存放子節點元素 Map<String, Object> mapSub = new HashMap<String, Object>(); // 遍歷當前元素的屬性存入子節點map中 attributeIterator(elmt, mapSub); // 獲取所有子節點 List<Element> elements = (List<Element>) elmt.elements(); // 遍歷子節點 for (Element elmtSub : elements) { // 遞迴呼叫轉換map element2map(elmtSub, mapSub); } // 當前元素沒有子節點後 獲取當前map中的元素名所對應的值 Object first = map.get(name); if (null == first) { // 如果沒有將值存入map中 map.put(name, mapSub); } else { // 如果有,則為陣列物件 if (first instanceof List<?>) { attributeIterator(elmt, mapSub); ((List) first).add(mapSub); } else { List<Object> listSub = new ArrayList<Object>(); listSub.add(first); attributeIterator(elmt, mapSub); listSub.add(mapSub); map.put(name, listSub); } } } } /** * 遍歷元素屬性 * * @param elmt * @param map */ private void attributeIterator(Element elmt, Map<String, Object> map) { if (elmt != null) { Iterator ai = elmt.attributeIterator(); while (ai.hasNext()) { Attribute next = (Attribute) ai.next(); map.put(elmt.getName() + "." + next.getName(), next.getValue()); } } } public static void main(String args[]) throws DocumentException { String str = "<xml x=\"sd\"><ai><a code=\"1111\"><c>sdfsf</c></a><a code=\"1111\"><c>sdfsf</c></a><appid ref=\"com.web.business.controller\"><a code=\"2222\"><c>sdfsf</c></a><a code=\"3333\"><c>sdfsf</c></a><b>bbbbceshi</b></appid><appid ref=\"com.sdcloud.web.business.controller\"><a code=\"1000\">aaaa</a><b>bbbbceshi</b></appid><attach>支付測試</attach><body>APP支付測試</body><mch_id>10000100</mch_id><nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>" + "<notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url><out_trade_no>1415659990</out_trade_no><spbill_create_ip>14.23.150.211</spbill_create_ip>" + "<total_fee>1</total_fee><trade_type>APP</trade_type><sign>0CB01533B8C1EF103065174F50BCA001</sign></ai><ai><a code=\"1111\"><c>sdfsf</c></a><appid ref=\"com.web.business.controller\"><a code=\"2222\"><c>sdfsf</c></a><a code=\"3333\"><c>sdfsf</c></a><b>bbbbceshi</b></appid><appid ref=\"com.sdcloud.web.business.controller\"><a // code=\"1000\">aaaa</a><b>bbbbceshi</b></appid><attach>支付測試</attach><body>APP支付測試</body><mch_id>10000100</mch_id><nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>" + "<notify_url>http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php</notify_url><out_trade_no>1415659990</out_trade_no><spbill_create_ip>14.23.150.211</spbill_create_ip>" + "<total_fee>1</total_fee><trade_type>APP</trade_type><sign>0CB01533B8C1EF103065174F50BCA001</sign></ai></xml>"; List<Map<String, Object>> ps = new ParseXml().parseData(str, null); for (Map<String, Object> m : ps) { Iterator<Map.Entry<String, Object>> it = m.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Object> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } } // Map m = xml2map(str); // Iterator<Map.Entry<String, Object>> it = m.entrySet().iterator(); // while (it.hasNext()) { // Map.Entry<String, Object> entry = it.next(); // System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); // } // Map m1 = (Map) m.get("xml"); // Map m2 = (Map) m1.get("appid"); // System.out.println(m2.get("b")); } }