XMLをMap汎用アルゴリズム実装Javaバージョンに変換(Stax実装)
50413 ワード
現在のプロジェクトではXMLをMapに変換する必要があり,以下に独自のコード実装を示す.
その後、Domバージョンの実装を提供します.
各道の大神は各種の優良な実現を与えてください.
シーン:
プロジェクトではXMLテキスト文字列を解析する必要があり、XMLテキスト文字列をMap形式のオブジェクトにマッピングする必要があります.
必要:
1、性能向上のために、Staxで解析する必要がある
2、Map構造内部ではList、Map、Stringの3種類のデータフォーマットをサポートする必要がある
例:
その後、Domバージョンの実装を提供します.
各道の大神は各種の優良な実現を与えてください.
シーン:
プロジェクトではXMLテキスト文字列を解析する必要があり、XMLテキスト文字列をMap形式のオブジェクトにマッピングする必要があります.
必要:
1、性能向上のために、Staxで解析する必要がある
2、Map構造内部ではList、Map、Stringの3種類のデータフォーマットをサポートする必要がある
例:
: Map
* :<name>BurceLiu</name><age>18</age>
* Map :{age=18, name=BurceLiu}
: Map ,Map Map
* :<student><name>BurceLiu</name><age>18</age></student>
* Map :{student={age=18, name=BurceLiu}}
: Map ,Map List ,List Map
* :<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}]}
: Map ,Map Map,Map List
* :<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}]}}
: List
* :<str>str1</str><str>str2</str><str>str3</str>
* Map :{str=[str1, str2, str3]}
1、
, 2
public interface IXMLParser {
/**
* xml Map
* @param xml
* @return
*/
public Map<String, Object> parse(String xml);
/**
*
* , ,
*/
public void init();
}
2、 クラス
な クラスは、Stax を いてこのスキームを する
1 package com.juxtapose.xml.parser;
2
3 import java.io.StringReader;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.concurrent.atomic.AtomicInteger;
9
10 import javax.xml.stream.XMLInputFactory;
11 import javax.xml.stream.XMLStreamConstants;
12 import javax.xml.stream.XMLStreamReader;
13
14 /**
15 * xml .<br>
16 * xml Map .<br>
17 * Map、List、String .<br>
18 *
19 * @author burceliu (mailto:[email protected])
20 */
21
22 public class XMLParserStaxImpl implements IXMLParser {
23
24 public static final String NODE_ELEMENT_NAME = "root";
25 public static final String NODE_DEFAULT_VALUE = "";
26
27 private String rootName; //
28 private String defaultNullValue; //
29
30 private static XMLInputFactory factory = XMLInputFactory.newInstance();
31 static {
32 factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
33 factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
34 }
35
36 /* (non-Javadoc)
37 * @see com.juxtapose.xml.parser.IXMLParser#parse(java.lang.String)
38 */
39 public Map<String, Object> parse(String xml) {
40 Map<String, Object> map = new HashMap<String, Object>();
41 StringReader stringReader = null;
42 try{
43 stringReader = new StringReader(xml);
44 XMLStreamReader reader = factory.createXMLStreamReader(stringReader);
45 map = parse(reader);
46 }catch(Throwable t){
47 throw new RuntimeException(t);
48 }finally{
49 if(null != stringReader){
50 try {
51 stringReader.close();
52 } catch (Exception e) {
53 throw new RuntimeException(e);
54 }
55 }
56 }
57 return map;
58 }
59
60 /* (non-Javadoc)
61 * @see com.juxtapose.xml.parser.IXMLParser#init()
62 */
63 public void init() {
64 if(this.getRootName() == null){
65 this.setRootName(NODE_ELEMENT_NAME);
66 this.setDefaultNullValue(NODE_DEFAULT_VALUE);
67 }
68 }
69
70 @SuppressWarnings({ "unchecked", "rawtypes" })
71 private Map<String, Object> parse(XMLStreamReader reader) throws Throwable{
72 Map<String, Object> map = new HashMap<String, Object>();
73 Map<String, Object> currentMap = map;
74 int event = reader.getEventType();
75 List<String> names = new ArrayList<String>();
76 NodeAmount nodeAmount = new NodeAmount();
77 int taglength = 0;
78 String tagName = null;
79 String tagValue = this.defaultNullValue;
80 while(true){
81 switch (event) {
82 case XMLStreamConstants.START_DOCUMENT:
83 break;
84 case XMLStreamConstants.START_ELEMENT:
85 tagValue = this.defaultNullValue;
86 tagName = reader.getLocalName();
87 if(this.rootName.equals(tagName)){
88 break;
89 }
90 names.add(tagName);
91 taglength++;
92
93 currentMap = map;
94 if(taglength > 1){
95 for(int i=0;i< taglength-1;i++){
96 Object object = currentMap.get(names.get(i));
97 if(null == object){
98 object = new HashMap<String, Object>();
99 currentMap.put(names.get(i), object);
100 currentMap = (Map<String, Object>)object;
101 }else{
102 int currentTagNameSize = nodeAmount.getSize(i + 1 + "" + names.get(i));
103 if( currentTagNameSize > 1){
104 if(object instanceof Map){
105 List parentList = new ArrayList();
106 parentList.add(object);
107 Map tempMap = new HashMap();
108 parentList.add(tempMap);
109 currentMap.put(names.get(i), parentList);
110 currentMap = tempMap;
111 }else if(object instanceof List){
112 List parentList = (List)object;
113 int parentListSize = parentList.size();
114 if(parentListSize != currentTagNameSize){
115 Map tempMap = new HashMap();
116 parentList.add(tempMap);
117 currentMap = tempMap;
118 }else{
119 Map tempMap = (Map) parentList.get(parentList.size()-1);
120 currentMap = tempMap;
121 }
122 }
123 }else{
124 currentMap = (Map<String, Object>)object;
125 }
126 }
127 }
128 }
129 nodeAmount.add(names.size() + tagName);
130 break;
131 case XMLStreamConstants.CHARACTERS:
132 tagValue = reader.getText();
133 break;
134 case XMLStreamConstants.END_ELEMENT:
135 tagName = reader.getLocalName();
136 if(this.rootName.equals(tagName)){
137 break;
138 }
139
140 currentMap = map;
141 if(taglength > 1){
142 for(int i=0;i< taglength-1;i++){
143 Object object = currentMap.get(names.get(i));
144 if(null == object){
145 //nothing to do
146 }else{
147 if(object instanceof List){
148 List list = (List)object;
149 currentMap = (Map)list.get(list.size() -1);
150 }else if(object instanceof Map){
151 currentMap = (Map)object;
152 }
153 }
154 }
155 }
156
157 Object oldValue = currentMap.get(tagName);
158 if(!currentMap.containsKey(tagName)){
159 currentMap.put(tagName, tagValue);
160 nodeAmount.remove(names.size() + tagName);
161 }else{
162 if(oldValue instanceof List){
163 List list = (List)oldValue;
164 if(list.size() > 0){
165 Object obj = list.get(0);
166 if(obj instanceof String){
167 ((List)oldValue).add(tagValue);
168 nodeAmount.remove(names.size() + tagName);
169 }
170 }
171 }else if(oldValue instanceof Map){
172
173 }else{
174 List tmpList = new ArrayList();
175 currentMap.put(tagName, tmpList);
176 tmpList.add(oldValue);
177 tmpList.add(tagValue);
178 nodeAmount.remove(names.size() + tagName);
179 }
180 }
181
182 tagValue = this.defaultNullValue;
183 names.remove(names.size()-1);
184 taglength--;
185 break;
186 case XMLStreamConstants.END_DOCUMENT:
187 break;
188 }
189
190 if (!reader.hasNext()) {
191 break;
192 }
193 event = reader.next();
194 }
195 return map;
196 }
197
198 public String getRootName() {
199 return rootName;
200 }
201
202 public void setRootName(String rootName) {
203 this.rootName = rootName;
204 }
205
206 public String getDefaultNullValue() {
207 return defaultNullValue;
208 }
209
210 public void setDefaultNullValue(String defaultNullValue) {
211 this.defaultNullValue = defaultNullValue;
212 }
213
214 class NodeAmount{
215 private Map<String, AtomicInteger> map =new HashMap<String, AtomicInteger>();
216
217 public void add(String nodeName){
218 AtomicInteger integer = map.get(nodeName);
219 if(null == integer){
220 integer = new AtomicInteger(0);
221 map.put(nodeName, integer);
222 }
223 integer.incrementAndGet();
224 }
225
226 public void remove(String nodeName){
227 AtomicInteger integer = map.get(nodeName);
228 if(null != integer){
229 integer.decrementAndGet();
230 }
231 }
232
233 public int getSize(String nodeName){
234 AtomicInteger integer = map.get(nodeName);
235 if(null == integer){
236 integer = new AtomicInteger(0);
237 map.put(nodeName, integer);
238 }
239 return integer.intValue();
240 }
241 }
242
243 }
244
245 /*
246 *
247 * $Log$
248 */
3、ユニットテスト 1 package test.com.juxtapose.xml.parser;
2
3 import java.util.Map;
4
5 import org.junit.After;
6 import org.junit.AfterClass;
7 import org.junit.Before;
8 import org.junit.BeforeClass;
9 import org.junit.Test;
10
11 import com.juxtapose.xml.parser.IXMLParser;
12 import com.juxtapose.xml.parser.XMLParserStaxImpl;
13
14 /**
15 *
16 * @author burceliu (mailto:[email protected])
17 */
18
19 public class TestXMLParserStaxImpl {
20
21 /**
22 * @throws java.lang.Exception
23 */
24 @BeforeClass
25 public static void setUpBeforeClass() throws Exception {
26 }
27
28 /**
29 * @throws java.lang.Exception
30 */
31 @AfterClass
32 public static void tearDownAfterClass() throws Exception {
33 }
34
35 /**
36 * @throws java.lang.Exception
37 */
38 @Before
39 public void setUp() throws Exception {
40 }
41
42 /**
43 * @throws java.lang.Exception
44 */
45 @After
46 public void tearDown() throws Exception {
47 }
48
49 @Test
50 public void test() {
51 IXMLParser parser = new XMLParserStaxImpl();
52 parser.init();
53 String xml = "<root><student><name>BurceLiu</name><age>18</age></student></root>";
54 Map<String, Object> result = parser.parse(xml);
55 System.out.println(result);
56 xml = "<root><student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student></root>";
57 result = parser.parse(xml);
58 System.out.println(result);
59 xml = "<root><str>str1</str><str>str2</str><str>str3</str></root>";
60 result = parser.parse(xml);
61 System.out.println(result);
62 xml = "<root><students><student><name>BurceLiu</name><age>18</age></student><student><name>BurceLi</name><age>28</age></student></students></root>";
63 result = parser.parse(xml);
64 System.out.println(result);
65 xml = "<root><name>BurceLiu</name><age>18</age></root>";
66 result = parser.parse(xml);
67 System.out.println(result);
68 }
69
70 }
71
72 /*
73 *
74 * $Log$
75 */
4、テスト
コンソールの を します.{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}
か があれば[email protected] と を ります.