XML转换为Map通用算法实现(Stax实现)
来源:互联网 发布:精易编程助手教程 编辑:程序博客网 时间:2024/06/08 17:07
目前项目中需要将XML转换为Map,下面给出了自己的代码实现。请各路大神提供更好的代码实现。
场景:
在项目中需要解析XML文本字符串,需要将XML文本字符串映射为Map格式的对象。
需求:
1、为了提高性能,需要使用Stax进行解析
2、Map结构内部需要支持List、Map、String三种数据格式
示例:
例一: * 字符串:<name>BurceLiu</name><age>18</age> * 转换为的Map结构:{age=18, name=BurceLiu}
例二: * 字符串:<student><name>BurceLiu</name><age>18</age></student> * 转换为的Map结构:{student={age=18, name=BurceLiu}}
例三: * 字符串:<student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student> * 转换为的Map结构:{student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}
例四: * 字符串:<students><student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student></students> * 转换为的Map结构:{students={student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}}
例五: * 字符串:<str>str1</str><str>str2</str><str>str3</str> * 转换为的Map结构:{str=[str1, str2, str3]}
代码实现
定义解析接口,提供2个核心方法
public interface IXMLParser {/** * xml格式字符串转换为Map * @param xml * @return */public Map<String, Object> parse(String xml);/** * 初始化动作 * 可以设置初始化动作,例如根节点名称, */public void init();}具体实现类,采用Stax技术实现该方案
package com.juxtapose.xml.parser;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;import javax.xml.stream.XMLInputFactory;import javax.xml.stream.XMLStreamConstants;import javax.xml.stream.XMLStreamReader;/** * xml字符串解析器实现类.<br> * xml字符串转换为Map对象.<br> * 转换后的数据类型为Map、List、String三种数据类型.<br> * * @author burceliu (mailto:jxta.liu@gmail.com) */public class XMLParserStaxImpl implements IXMLParser {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); }/* (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() */public 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();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.START_ELEMENT: tagValue = this.defaultNullValue; tagName = reader.getLocalName(); if(this.rootName.equals(tagName)){ break; } names.add(tagName); taglength++; currentMap = map; if(taglength > 1){ for(int i=0;i< taglength-1;i++){ Object object = currentMap.get(names.get(i)); 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();}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();}}}/* * 修改历史 * $Log$ */
单元测试:
package test.com.juxtapose.xml.parser;import java.util.Map;import org.junit.After;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import com.juxtapose.xml.parser.IXMLParser;import com.juxtapose.xml.parser.XMLParserStaxImpl;/** * * @author burceliu (mailto:jxta.liu@gmail.com) */public class TestXMLParserStaxImpl {/** * @throws java.lang.Exception */@BeforeClasspublic static void setUpBeforeClass() throws Exception {}/** * @throws java.lang.Exception */@AfterClasspublic static void tearDownAfterClass() throws Exception {}/** * @throws java.lang.Exception */@Beforepublic void setUp() throws Exception {}/** * @throws java.lang.Exception */@Afterpublic void tearDown() throws Exception {}@Testpublic void test() {IXMLParser parser = new XMLParserStaxImpl();parser.init();String xml = "<root><student><name>BurceLiu</name><age>18</age></student></root>";Map<String, Object> result = parser.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 = parser.parse(xml);System.out.println(result);xml = "<root><str>str1</str><str>str2</str><str>str3</str></root>";result = parser.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 = parser.parse(xml);System.out.println(result);xml = "<root><name>BurceLiu</name><age>18</age></root>";result = parser.parse(xml);System.out.println(result);}}/* * 修改历史 * $Log$ */
观察控制台的输出结果:
{student={age=18, name=BurceLiu}}{student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}{str=[str1, str2, str3]}{students={student=[{age=18, name=BurceLiu}, {age=28, name=BurceLi}]}}{age=18, name=BurceLiu}
0 0
- XML转换为Map通用算法实现(Stax实现)
- java实现对象转换为map、xml字符串转化为map、map转化为xml字符串
- XML转换为Map
- Dom4j实现xml到map转换
- 通过反射实现map转换为struct
- DOM方式解析XML文档(另2种方式为SAX,STAX),(第二种直接用sax方式用java类实现)
- 实现把字典转换为XML数据
- 阿拉伯数字 转换为 汉字数字 算法实现
- delphi7 xml通用解析转换为stringgrid
- Java实现将Map转换为List的小代码
- Java实现将Map转换为List的小代码
- 对象转换为Map集合,使用JSONObject实现
- XML之StAX(一)
- XML之StAX(二)
- 利用XML实现通用WEB报表打印(实现篇)
- 使用Introspector(Java内省机制)实现Map转换为JavaBean
- mybatis枚举自动转换(通用转换处理器实现)
- XML数据转换为Map工具类
- Study Html《document.compatMode属性》
- 高度,能量守恒
- git 大全
- [转] Ramfs与Tmpfs的使用
- Android 常用编译命令
- XML转换为Map通用算法实现(Stax实现)
- AIX上增加逻辑卷时报错误0516-787 extendlv: Maximum allocation for logical volume jdelv02 is 512
- 程序员必须知道的几个国外IT网站
- DragSortListView拖动排序的ListView,同时支持ListView滑动item删除
- leetcode_71_Simplify Path
- 模仿百度卫士手机版应用源码项目最新版更新版
- 在32及64位系统中拒绝访问 ProgID: "excel.application"及配置Microsoft Excel Application权限解决方案
- 19.Spring_事务的传播行为以及其他属性
- D2_1 安装模拟器Genymotion