引用
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=恭喜,提交成功}}
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; } }