xml 轉換 map (包括屬性和相同元素處理)
阿新 • • 發佈:2019-02-08
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"));
}
}