java xml to map / xml转map 带属性

参照:
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"
  ]
 }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值