xml 字符串解析成通用的map

引用
Stax解析技术:快速高效,根据流的形式解析xml,比dom解析技术更加快,dom解析技术是基于文档结构树的,会把整个dom文件树加载到内存进行解析

package com.nnk.upstream.util;

/**
 * Created with IntelliJ IDEA.
 * User: y
 * Date: 2016/5/27
 * Time: 17:09
 * email: [email protected]
 * To change this template use File | Settings | File Templates.
 */

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * xml字符串解析器实现类.<br>
 * xml字符串转换为Map对象.<br>
 * 转换后的数据类型为Map、List、String三种数据类型.<br>
 *
 *
 */

public class XmlMapPharser {

    public static final String NODE_ELEMENT_NAME = "root";
    public static final String NODE_DEFAULT_VALUE = "";

    private String rootName;            //根节点
    private String defaultNullValue;    //节点没有值的情况下默认值

    private static XMLInputFactory factory = XMLInputFactory.newInstance();
    static {
        factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
        factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
    }
    public XmlMapPharser(){
        init();
    }
    /* (non-Javadoc)
     * @see com.juxtapose.xml.parser.IXMLParser#parse(java.lang.String)
     */
    public Map<String, Object> parse(String xml) {
        Map<String, Object> map = new HashMap<String, Object>();
        StringReader stringReader = null;
        try{
            stringReader = new StringReader(xml);
            XMLStreamReader reader = factory.createXMLStreamReader(stringReader);
            map = parse(reader);
        }catch(Throwable t){
            throw new RuntimeException(t);
        }finally{
            if(null != stringReader){
                try {
                    stringReader.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return map;
    }

    /* (non-Javadoc)
     * @see com.juxtapose.xml.parser.IXMLParser#init()
     */
    private void init() {
        if(this.getRootName() == null){
            this.setRootName(NODE_ELEMENT_NAME);
            this.setDefaultNullValue(NODE_DEFAULT_VALUE);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private Map<String, Object> parse(XMLStreamReader reader) throws Throwable{
        Map<String, Object> map = new HashMap<String, Object>();
        Map<String, Object> currentMap = map;
        int event = reader.getEventType();
        //xml标签顺序
        List<String> names = new ArrayList<String>();
        NodeAmount nodeAmount = new NodeAmount();
        int taglength = 0;
        String tagName = null;
        String tagValue = this.defaultNullValue;
        while(true){
            switch (event) {
                case XMLStreamConstants.START_DOCUMENT:
                    break;
                case XMLStreamConstants.ATTRIBUTE:

                    break;
                case XMLStreamConstants.START_ELEMENT:
                    tagValue = this.defaultNullValue;
                    tagName = reader.getLocalName();
                    if(this.rootName.equals(tagName)){
                        break;
                    }
                    names.add(tagName);
                    taglength++;



                    currentMap = map;
                    for (int i=0;i<reader.getAttributeCount();i++){
                        String attribute = "attribute-"+reader.getAttributeLocalName(i);
//添加属性值
//                        names.add(attribute);
                        Object object = map.get(tagName);
                        if(null == object){
                            Map attrmap = new HashMap();
                            attrmap.put(attribute,reader.getAttributeValue(i));
                            map.put(tagName,attrmap);
                        }else if(object instanceof Map){
                            Map object1 = (Map) object;
                            object1.put(attribute,reader.getAttributeValue(i));
                        }
                    }
                    if(taglength > 1){
                        for(int i=0;i< taglength-1;i++){
                            //root>student>attribute-version>attribute-name>name>age>
                            String name = names.get(i);
                            Object object = currentMap.get(name);
                            if(null == object){
                                object = new HashMap<String, Object>();
                                currentMap.put(names.get(i), object);
                                currentMap = (Map<String, Object>)object;
                            }else{
                                int currentTagNameSize = nodeAmount.getSize(i + 1 + "" + names.get(i));
                                if( currentTagNameSize > 1){
                                    if(object instanceof Map){
                                        List parentList = new ArrayList();
                                        parentList.add(object);
                                        Map tempMap = new HashMap();
                                        parentList.add(tempMap);
                                        currentMap.put(names.get(i), parentList);
                                        currentMap = tempMap;
                                    }else if(object instanceof List){
                                        List parentList = (List)object;
                                        int parentListSize = parentList.size();
                                        if(parentListSize != currentTagNameSize){
                                            Map tempMap = new HashMap();
                                            parentList.add(tempMap);
                                            currentMap = tempMap;
                                        }else{
                                            Map tempMap = (Map) parentList.get(parentList.size()-1);
                                            currentMap = tempMap;
                                        }
                                    }
                                }else{
                                    currentMap = (Map<String, Object>)object;
                                }
                            }
                        }
                    }
                    nodeAmount.add(names.size() + tagName);

                    break;
                case XMLStreamConstants.CHARACTERS:
                    tagValue = reader.getText();
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    tagName = reader.getLocalName();
                    if(this.rootName.equals(tagName)){
                        break;
                    }

                    currentMap = map;
                    if(taglength > 1){
                        for(int i=0;i< taglength-1;i++){
                            Object object = currentMap.get(names.get(i));
                            if(null == object){
                                //nothing to do
                            }else{
                                if(object instanceof List){
                                    List list = (List)object;
                                    currentMap = (Map)list.get(list.size() -1);
                                }else if(object instanceof Map){
                                    currentMap = (Map)object;
                                }
                            }
                        }
                    }

                    Object oldValue = currentMap.get(tagName);
                    if(!currentMap.containsKey(tagName)){
                        currentMap.put(tagName, tagValue);
                        nodeAmount.remove(names.size() + tagName);
                    }else{
                        if(oldValue instanceof List){
                            List list = (List)oldValue;
                            if(list.size() > 0){
                                Object obj = list.get(0);
                                if(obj instanceof String){
                                    ((List)oldValue).add(tagValue);
                                    nodeAmount.remove(names.size() + tagName);
                                }
                            }
                        }else if(oldValue instanceof Map){

                        }else{
                            List tmpList = new ArrayList();
                            currentMap.put(tagName, tmpList);
                            tmpList.add(oldValue);
                            tmpList.add(tagValue);
                            nodeAmount.remove(names.size() + tagName);
                        }
                    }

                    tagValue = this.defaultNullValue;
                    names.remove(names.size()-1);
                    taglength--;
                    break;
                case XMLStreamConstants.END_DOCUMENT:
                    break;
            }

            if (!reader.hasNext()) {
                break;
            }
            event = reader.next();
        }
        return map;
    }

    public String getRootName() {
        return rootName;
    }

    public void setRootName(String rootName) {
        this.rootName = rootName;
    }

    public String getDefaultNullValue() {
        return defaultNullValue;
    }

    public void setDefaultNullValue(String defaultNullValue) {
        this.defaultNullValue = defaultNullValue;
    }

    class NodeAmount{
        private Map<String, AtomicInteger> map =new HashMap<String, AtomicInteger>();

        public void add(String nodeName){
            AtomicInteger integer = map.get(nodeName);
            if(null == integer){
                integer = new AtomicInteger(0);
                map.put(nodeName, integer);
            }
            integer.incrementAndGet();//+1
        }

        public void remove(String nodeName){
            AtomicInteger integer = map.get(nodeName);
            if(null != integer){
                integer.decrementAndGet();
            }
        }

        public int getSize(String nodeName){
            AtomicInteger integer = map.get(nodeName);
            if(null == integer){
                integer = new AtomicInteger(0);
                map.put(nodeName, integer);
            }
            return integer.intValue();
        }
    }

}

引用
测试样例:

package com.nnk.redis;

import com.nnk.upstream.util.MapUtils;
import com.nnk.upstream.util.XmlMapPharser;
import org.junit.Before;
import org.junit.Test;

import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: y
 * Date: 2016/5/27
 * Time: 17:13
 * email: [email protected]
 * To change this template use File | Settings | File Templates.
 */
public class MapPharserUtils {
    private XmlMapPharser pharser;
    @Test
    public void testPharseXml() throws Exception {

        String xml = "<root><student><name>BurceLiu</name><age>18</age></student></root>";
        Map<String, Object> result = pharser.parse(xml);
        System.out.println(result);
        xml = "<root><student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student></root>";
        result = pharser.parse(xml);
        System.out.println(result);
        xml = "<root><str>str1</str><str>str2</str><str>str3</str></root>";
        result = pharser.parse(xml);
        System.out.println(result);
        xml = "<root><students><student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student></students></root>";
        result = pharser.parse(xml);
        System.out.println(result.get("students"));
        System.out.println(MapUtils.getObject(result,"students.student"));


        xml = "<root><name>BurceLiu</name><age>18</age></root>";
        result = pharser.parse(xml);
        System.out.println(result);
        xml = "<?xml version=\'1.0\' encoding=\'UTF-8\'?>" +
                "<PayPlatRequestParameter>" +
                "<CTRL-INFO WEBSVRNAME=\'充值卡预订\' WEBSVRCODE=\'B00002\' APPFROM=\'0990000010\' SERNUM=\'987654321\' APPDATE=\'20111203\'/>" +
                "<PARAMETERS>" +
                "<BILLORGID>9999009999019001</BILLORGID>" +
                "<ORDERPRICESUM>990</ORDERPRICESUM>" +
                "<ORDERREALPRICESUM>990</ORDERREALPRICESUM>" +
                "<ORDERS>" +
                "<CARDSEQ>3</CARDSEQ>" +
                "<CARDPRICESEQ>310001</CARDPRICESEQ>" +
                "<ORDERNUM>1</ORDERNUM>" +
                "<CARDAMT>990</CARDAMT>" +
                "<ORDERPRICE>990</ORDERPRICE>" +
                "<RANDOMRATE>1.0</RANDOMRATE>" +
                "<TEXT1></TEXT1>" +
                "<TEXT2></TEXT2>" +
                "<TEXT3></TEXT3>" +
                "<TEXT4></TEXT4>" +
                "<TEXT5></TEXT5>" +
                "</ORDERS>" +
                "<TEXT1></TEXT1>" +
                "<TEXT2></TEXT2>" +
                "<TEXT3></TEXT3>" +
                "<TEXT4></TEXT4>" +
                "<TEXT5></TEXT5>" +
                "</PARAMETERS>" +
                "<MAC>669e15fbc5341d4a021d0d725bddc234</MAC>" +
                "</PayPlatRequestParameter>";
        result = pharser.parse(xml);
        System.out.println(result);
        System.out.println(MapUtils.getObject(result,"PayPlatRequestParameter.PARAMETERS.ORDERS.RANDOMRATE"));
        System.out.println(MapUtils.getObject(result,"CTRL-INFO.attribute-WEBSVRNAME"));

        xml="<?xml version=\"1.0\" encoding=\"GB2312\"?>" +
                "<response>" +
                "<result>true</result>" +
                "<code>100</code>" +
                "<msg>恭喜,提交成功</msg>" +
                "<pno> TOPUP10000013610</pno>" +
                "<data>" +
                "<sid>110922133648293754</sid>" +
                "<ste>0</ste>" +
                "<cid>yibao1228</cid>" +
                "<pid>0103</pid>" +
                "<oid>TOPUP10000013610</oid>" +
                "<pn>13426200000</pn>" +
                "<fm>30.00</fm>" +
                "<dm>29.00</dm>" +
                "<info1></info1>" +
                "<info2></info2>" +
                "<info3></info3>" +
                "<ft></ft>" +
                "<error></error>" +
                "<msg></msg>" +
                "</data>" +
                "</response>";
        result = pharser.parse(xml);
        System.out.println(result);

    }
    @Test
    public void testPharseXml1() throws Exception {
        String xml = "<root><student version=\"1.0\" name=\"liuy\"><name agent=\"ddddd\">BurceLiu</name><age>18</age></student></root>";
        Map<String, Object> result = pharser.parse(xml);
        System.out.println(result);
    }
    @Before
    public void setUp() throws Exception {
        pharser = new XmlMapPharser();
    }
}


引用
解析成map 之后我们需要获取值,可以采用key.key1.key2的格式获取到值
test 输出值如下:
{student={age=18, name=BurceLiu}}
{student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}
{str=[str1, str2, str3]}
{student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}
[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]
{age=18, name=BurceLiu}
{PayPlatRequestParameter={PARAMETERS={ORDERS={RANDOMRATE=1.0, ORDERPRICE=990, ORDERNUM=1, TEXT5=, CARDAMT=990, TEXT2=, TEXT1=, TEXT4=, TEXT3=, CARDPRICESEQ=310001, CARDSEQ=3}, ORDERPRICESUM=990, TEXT5=, ORDERREALPRICESUM=990, TEXT2=, TEXT1=, TEXT4=, TEXT3=, BILLORGID=9999009999019001}, CTRL-INFO=, MAC=669e15fbc5341d4a021d0d725bddc234}, CTRL-INFO={attribute-WEBSVRCODE=B00002, attribute-WEBSVRNAME=充值卡预订, attribute-SERNUM=987654321, attribute-APPDATE=20111203, attribute-APPFROM=0990000010}}
1.0
充值卡预订
{response={result=true, data={ste=0, sid=110922133648293754, error=, pid=0103, msg=, cid=yibao1228, fm=30.00, oid=TOPUP10000013610, dm=29.00, info1=, pn=13426200000, ft=, info3=, info2=}, code=100, pno= TOPUP10000013610, msg=恭喜,提交成功}}

package com.nnk.upstream.util;

import com.alibaba.fastjson.JSONObject;
import com.nnk.upstream.entity.proxy.ProctolTypeEnum;

import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: y
 * Date: 2016/6/2
 * Time: 11:42
 * email: [email protected]
 * To change this template use File | Settings | File Templates.
 */
public class MapUtils {

    public static Object getObject(Map map,String keyname){
        String[] keynames = keyname.split("\\.");
        if(keynames.length==1){
            return map.get(keynames[0]);
        }
        Object object = map.get(keynames[0]);
        JSONObject jsonObject = null;
        if(object instanceof JSONObject) {
            jsonObject = (JSONObject) object;
            for(int i = 1;i <=keynames.length;i++){
                jsonObject = (JSONObject) jsonObject.get(keynames[i]);
            }
            return jsonObject;
        }else if(object instanceof Map){
            Map map1 = (Map) object;
            Object object1 = null;
            for(int i = 1;i <keynames.length;i++){
                object1 = map1.get(keynames[i]);
                if(object1 instanceof Map){
                    Map result = (Map) object1;
                    map1 = result;
                }
            }
            return object1;
        }
        return null;
   }

    /**
     * <p>parse the response's string to a map</p>
     * @param resp response's string
     * @param protoclType response's protoclType
     * @return a map of result
     */
    public static Map getResultMap(String resp, String protoclType) {
        Map map = null;
        if(ProctolTypeEnum.JSON.getName().equals(protoclType)){
            map = JsonUtils.phareToMap(resp);
        }else if(ProctolTypeEnum.FORM.getName().equals(protoclType)){
            map = new HashMap();
            String[] contents = resp.split("[=&|~!@#$%^&*]+");
            if(resp.contains("=")&&resp.contains("&")&&!resp.matches(".*[~!@#$%^&*]+.*")){
                int i=0;
                for (;i<contents.length;i=i+2){
                    String key = contents[i];
                    String value =contents[i+1];
                    map.put(key,value);
                }
            }else {
                int i = 0;
                for (String content:contents){

                    String key = "Str-index"+i;
                    map.put(key,content);
                    i++;
                }
            }
        }else if(ProctolTypeEnum.XML.getName().equals(protoclType)){
            XmlMapPharser mapPharser = new XmlMapPharser();
            map = mapPharser.parse(resp);
        }
        return map;
    }
}

猜你喜欢

转载自a153870727.iteye.com/blog/2304508
今日推荐