java xml to map / xml转map 带属性
程序员文章站
2022-05-19 15:39:26
...
参照:
http://happyqing.iteye.com/blog/2317570
代码
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;
@SuppressWarnings({ "rawtypes", "unchecked" })
public class XmlUtil2 {
public static void main(String[] args) throws DocumentException, IOException {
String textFromFile = FileUtils.readFileToString(new File("D:/_zyy_Document/test/sample.xml"),"UTF-8");
Document doc = DocumentHelper.parseText(textFromFile);
Map<String, Object> map = (Map<String, Object>) xmlToMapWithAttr(doc.getRootElement());
// Map<String, Object> map = xmlToMap(textFromFile, false);
// long begin = System.currentTimeMillis();
// for(int i=0; i<1000; i++){
// map = (Map<String, Object>) xml2mapWithAttr(doc.getRootElement());
// }
// System.out.println("耗时:"+(System.currentTimeMillis()-begin));
JSON json = JSONObject.fromObject(map);
System.out.println(json.toString(1)); // 格式化输出
// System.out.println(map); // 格式化输出
}
/**
* xml转map 不带属性
* @param xmlStr
* @param needRootKey 是否需要在返回的map里加根节点键
* @return
* @throws DocumentException
*/
public static Map xmlToMap(String xmlStr, boolean needRootKey) throws DocumentException {
Document doc = DocumentHelper.parseText(xmlStr);
Element root = doc.getRootElement();
Map<String, Object> map = (Map<String, Object>) xmlToMap(root);
if(root.elements().size()==0 && root.attributes().size()==0){
return map;
}
if(needRootKey){
//在返回的map里加根节点键(如果需要)
Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put(root.getName(), map);
return rootMap;
}
return map;
}
/**
* xml转map 带属性
* @param xmlStr
* @param needRootKey 是否需要在返回的map里加根节点键
* @return
* @throws DocumentException
*/
public static Map xmlToMapWithAttr(String xmlStr, boolean needRootKey) throws DocumentException {
Document doc = DocumentHelper.parseText(xmlStr);
Element root = doc.getRootElement();
Map<String, Object> map = (Map<String, Object>) xmlToMapWithAttr(root);
if(root.elements().size()==0 && root.attributes().size()==0){
return map; //根节点只有一个文本内容
}
if(needRootKey){
//在返回的map里加根节点键(如果需要)
Map<String, Object> rootMap = new HashMap<String, Object>();
rootMap.put(root.getName(), map);
return rootMap;
}
return map;
}
/**
* xml转map 不带属性
* @param element
* @return
*/
private static Object xmlToMap(Element element) {
// System.out.println(element.getName());
Map<String, Object> map = new LinkedHashMap<String, Object>();
List<Element> elements = element.elements();
if (elements.size() == 0) {
map.put(element.getName(), element.getText());
if (!element.isRootElement()) {
return element.getText();
}
} else if (elements.size() == 1) {
map.put(elements.get(0).getName(), xmlToMap(elements.get(0)));
} else if (elements.size() > 1) {
// 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
// 构造一个map用来去重
Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
for (Element ele : elements) {
tempMap.put(ele.getName(), ele);
}
Set<String> keySet = tempMap.keySet();
for (String string : keySet) {
Namespace namespace = tempMap.get(string).getNamespace();
List<Element> elements2 = element.elements(new QName(string,
namespace));
// 如果同名的数目大于1则表示要构建list
if (elements2.size() > 1) {
List<Object> list = new ArrayList<Object>();
for (Element ele : elements2) {
if(StringUtils.isEmpty(ele.getText())) continue;
list.add(xmlToMap(ele));
}
map.put(string, list);
} else {
// 同名的数量不大于1则直接递归去
map.put(string, xmlToMap(elements2.get(0)));
}
}
}
return map;
}
/**
* xml转map 带属性
* @param element
* @return
*/
private static Object xmlToMapWithAttr(Element element) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
List<Element> elements = element.elements();
if (elements.size() == 0) {//没有子节点的情况 key - value
map.put(element.getName(), element.getText());
if (!element.isRootElement()) {
return element.getText();
}
} else if (elements.size() == 1) {//一个子节点的情况,map
map.put(elements.get(0).getName(),
xmlToMapWithAttr(elements.get(0)));
} else if (elements.size() > 1) {//多个子节点的情况,key-value、map、list 情况据需要考虑
// 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
// 构造一个map用来去重
Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
for (Element ele : elements) {
tempMap.put(ele.getName(), ele);
}
Set<String> keySet = tempMap.keySet();
for (String string : keySet) {
Namespace namespace = tempMap.get(string).getNamespace();
List<Element> elements2 = element.elements(new QName(string,
namespace));
// 如果同名的数目大于1则表示要构建list
if (elements2.size() > 1) {
List<Object> list = new ArrayList<Object>();
for (Element ele : elements2) {
if(StringUtils.isEmpty(ele.getText())) continue;
list.add(xmlToMapWithAttr(ele));
}
map.put(string, list);
} else if (elements2.size() == 1 && "List".equals(elements2.get(0).attributeValue("nodeType"))) {//如果同名的数据只有一个并且属性nodeType为List,则要构建list
List<Object> list = new ArrayList<Object>();
Element ele = elements2.get(0);
if(StringUtils.isEmpty(ele.getText())) continue;
list.add(xmlToMapWithAttr(ele));
map.put(string, list);
}else {
// 同名的数量不大于1则直接递归去
map.put(string, xmlToMapWithAttr(elements2.get(0)));
}
}
}
return map;
}
}
代码中用到的文件sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<PA_HEADER></PA_HEADER>
<PA_BODY>
<transationNo>123456789</transationNo>
<partnerCode>TEST</partnerCode>
<applicantInfo>
<name>ashi</name>
<certifacateType>01</certifacateType>
<certificateNo>342425199311205111</certificateNo>
</applicantInfo>
<insurentList nodeType="List">
<name>zyy1</name>
<certifacateType>01</certifacateType>
<certificateNo>342425199311205112</certificateNo>
</insurentList>
<planInfo nodeType="List">
<planName>plan1</planName>
<planCode>A</planCode>
<dutyInfo>
<dutyName>duty1</dutyName>
<dutyCode>a1</dutyCode>
</dutyInfo>
<dutyInfo>
<dutyName>duty2</dutyName>
<dutyCode>a2</dutyCode>
</dutyInfo>
<map>
<hello>hi</hello>
</map>
</planInfo>
<planInfo nodeType="List">
<planName>plan2</planName>
<planCode>B</planCode>
<dutyInfo nodeType="List">
<dutyName>duty3</dutyName>
<dutyCode>b1</dutyCode>
</dutyInfo>
<dutyInfo nodeType="List">
<dutyName>duty4</dutyName>
<dutyCode>b2</dutyCode>
</dutyInfo>
</planInfo>
<beneficiaryList nodeType="List">
<name>zyy4</name>
<certifacateType>01</certifacateType>
<certificateNo>342425199311205115</certificateNo>
</beneficiaryList>
<remark nodeType="List">1234</remark>
<remark nodeType="List">5678</remark>
</PA_BODY>
</root>
结果
{
"PA_HEADER": "",
"PA_BODY": {
"transationNo": "123456789",
"partnerCode": "TEST",
"applicantInfo": {
"name": "ashi",
"certifacateType": "01",
"certificateNo": "342425199311205111"
},
"insurentList": [ {
"name": "zyy1",
"certifacateType": "01",
"certificateNo": "342425199311205112"
}],
"planInfo": [
{
"planName": "plan1",
"planCode": "A",
"dutyInfo": [
{
"dutyName": "duty1",
"dutyCode": "a1"
},
{
"dutyName": "duty2",
"dutyCode": "a2"
}
],
"map": {"hello": "hi"}
},
{
"planName": "plan2",
"planCode": "B",
"dutyInfo": [
{
"dutyName": "duty3",
"dutyCode": "b1"
},
{
"dutyName": "duty4",
"dutyCode": "b2"
}
]
}
],
"beneficiaryList": [ {
"name": "zyy4",
"certifacateType": "01",
"certificateNo": "342425199311205115"
}],
"remark": [
"1234",
"5678"
]
}
}