The current project needs to convert XML to map, and the following gives its own code implementation. Ask the great gods to provide better code implementations.
Scene:
XML text strings need to be parsed in the project, and XML text strings need to be mapped to objects in map format.
Demand:
1, in order to improve performance, need to use Stax to parse
2, map structure inside need to support list, map, string three data format
Example:
Example one: * string:<name>burceliu</name><age>18</age> * converted to the map structure: {age=18, Name=burceliu}
Example two: * string:<student><name>burceliu</name><age>18</age></student> * converted to the map structure: { Student={age=18, Name=burceliu}}
Example three: * String: <student><name>burceliu</name><age>18</age></student><student ><name>BurceLi</name><age>28</age></student> * converted to the map structure: {student=[{age=18, name =burceliu}, {age=28, name=burceli}]}
Example four: * String: <students><student><name>burceliu</name><age>18</age></student ><student><name>BurceLi</name><age>28</age></student></students> * Map structure converted to: {students={student=[{age=18, Name=burceliu}, {age=28, Name=burceli}]}}
Example five: * string:<str>str1</str><str>str2</str><str>str3</str> * converted to the map structure: {STR=[STR1 , STR2, STR3]}
Code implementation
Defines the parsing interface, providing 2 core methods
Public interface Ixmlparser {/** * XML format string converted to MAP * @param XML * @return */public map<string, object> Parse (string x ML);/** * Initialization action * can set initialization action, such as root node name, */public void Init ();}
Implementation class, using Stax technology to realize the scheme
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 string Parser implementation class .<br> * XML string converted to map object .<br> * Converted data type is map, List, String three data Types .<br> * * @author Burceliu (mailto:[email protected]) */public class Xmlparserstaximpl Implements Ixmlparser {public static final string node_element_name = "root";p ublic static final string Node_default_value = "";p rivate string rootname;//root node private string defaultnullvalue;//node without value default 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 Hash Map<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.star T_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 Li St = (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 A Rraylist (); 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> ();p ublic 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 atomicint Eger (0); Map.put (NodeName, Integer);} return Integer.intvalue ();}}} /* Change history * $Log $ */
Unit tests:
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:[email protected]) */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 VO ID setUp () throws Exception {}/** * @throws java.lang.Exception */@Afterpublic void TearDown () throws Exception {} @Testpub LIC void Test () {ixmlparser parser = new Xmlparserstaximpl ();p arser.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);}} /* Change history * $Log $ */
Observe the output of the console:
{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}
XML conversion to map general algorithm implementation (Stax implementation)