Summary
In the network, data interaction is usually done in the format of XML and Json, so parsing the data in these two formats is a necessary function in Android development. This paper briefly describes the common ways of Xml and Json parsing in Android development with a simple example, which is only for learning and sharing.
XML parsing
Android provides three ways to parse XML: SAX (Simple API XML), DOM (Document Object Model), and PULL. This article focuses on how Pull parses Xml.
PULL parsing Xml advantages: PULL parser is compact, fast, simple and easy to use, very suitable for Android mobile devices, Android system is also used to parse a variety of XML PULL parser, Android official recommendation developers use Pull parsing technology. Pull parsing technology is an open source technology developed by third parties, which can also be applied to JavaSE development.
Involving knowledge points
- XmlPullParser is an interface that provides basic functions for Pull-style parsing of XML.
- xmlPullParser.getEventType() returns the event type of the current node (such as START_TAG, END_TAG, TEXT, etc.).
- xmlPullParser.getName() gets the name of the current node.
- xmlPullParser.getAttributeCount() Gets the number of attributes corresponding to the current node.
- xmlPullParser.getText() gets the text content corresponding to the current node.
- xmlPullParser.getAttributeName(0) gets the name of the attribute.
- xmlPullParser.getAttributeValue(0) gets the corresponding value of the attribute.
- xmlPullParser.next() moves to the next event.
Xml file
Xml storage relative path: DemoXml app src main res xml test. XML [xml folder]
1 <bookstore> 2 <book category="COOKING"> 3 <title lang="en">Everyday Italian</title> 4 <author>Giada De Laurentiis</author> 5 <year>2005</year> 6 <price>30.00</price> 7 </book> 8 <book category="CHILDREN"> 9 <title lang="en">Harry Potter</title> 10 <author>J K. Rowling</author> 11 <year>2005</year> 12 <price>29.99</price> 13 </book> 14 <book category="WEB"> 15 <title lang="en">Learning XML</title> 16 <author>Erik T. Ray</author> 17 <year>2003</year> 18 <price>39.95</price> 19 </book> 20 </bookstore>
Xml parsing source code
1 /** 2 * Getting Xml content 3 * @param resources 4 * @param id 5 * @return 6 * @throws XmlPullParserException 7 * @throws IOException 8 */ 9 private List<String> xml_parser(Resources resources, int id) throws XmlPullParserException, IOException { 10 XmlPullParser xmlPullParser = resources.getXml(id); 11 List<String> lstContent=new ArrayList<String>(); 12 int eventType = xmlPullParser.getEventType(); 13 while (eventType != XmlPullParser.END_DOCUMENT) { 14 switch (eventType) { 15 case XmlPullParser.START_DOCUMENT://Document Start 16 Log.i(TAG, "xml_parser: START_DOCUMENT"); 17 break; 18 case XmlPullParser.END_DOCUMENT://End of Document 19 Log.i(TAG, "xml_parser: END_DOCUMENT"); 20 break; 21 case XmlPullParser.START_TAG://Mark (Element, Node) Start 22 Log.i(TAG, "xml_parser: START_TAG"); 23 String tagName = xmlPullParser.getName(); 24 //Some nodes do not have attribute values, so it needs to be judged, otherwise they will cross the boundary. 25 int count = xmlPullParser.getAttributeCount();//Get the number of attributes 26 String tagAttributeValue=""; 27 String tagAttributeName=""; 28 //String text =xmlPullParser.getText();//Not available here text 29 String content=""; 30 if (count > 0) { 31 tagAttributeName=xmlPullParser.getAttributeName(0); 32 tagAttributeValue = xmlPullParser.getAttributeValue(0); 33 content="Label="+tagName+"Property name="+tagAttributeName+"Attribute value="+tagAttributeValue; 34 }else{ 35 content="Label="+tagName; 36 } 37 lstContent.add(content); 38 break; 39 case XmlPullParser.TEXT: 40 String text =xmlPullParser.getText(); 41 lstContent.add("Node content="+text); 42 break; 43 case XmlPullParser.END_TAG://End of Mark 44 Log.i(TAG, "xml_parser: END_TAG"); 45 break; 46 } 47 eventType = xmlPullParser.next(); 48 } 49 return lstContent; 50 }
If the Xml file is too large, it is not suitable to execute in the Activity main thread. This article is executed in the Worker thread, as follows:
1 private static final String TAG="TAG"; 2 3 private static final int MSG_FINISH=0x0001; 4 5 private TextView tvMsg; 6 7 private Handler handler=new Handler(){ 8 @Override 9 public void handleMessage(Message msg) { 10 switch (msg.what){ 11 case MSG_FINISH: 12 List<String> lstContent=(List<String>)msg.obj; 13 for (String info :lstContent){ 14 tvMsg.append(info+"\r\n"); 15 } 16 break; 17 } 18 } 19 }; 20 21 public void bn_xml_parser_click(View view){ 22 tvMsg.setText(""); 23 new Thread(){ 24 @Override 25 public void run() { 26 try { 27 List<String> lstContent=xml_parser(getResources(),R.xml.test); 28 Message msg=handler.obtainMessage(); 29 msg.what=MSG_FINISH; 30 msg.obj=lstContent; 31 handler.sendMessage(msg); 32 } catch (XmlPullParserException e) { 33 e.printStackTrace(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 } 38 }.start(); 39 }
JSON parsing
Json is a lightweight data exchange format with good readability and easy to write. Mainstream technology in the industry provides a complete solution for data exchange between different platforms.
Involving knowledge points
- JSONObject represents an object in Json format.
- jsonObject.getString("key"); Gets the value in string format.
- jsonObject.getInt("key"); gets the value of type Int.
- jsonObject.getBoolean("key"); gets the value of bool type.
- jsonObject.getDouble("key"); Gets the value of the floating-point type.
- jsonObject.get("key"); returns an object of type Object.
- jsonObject.getJSONArray("key"); returns an object of data type.
- InputStream input stream.
Json file
Json stores relative paths: DemoXml app src main res raw test2. JSON [ray folder]
{ "name": "Xiao Ming", "age": 14, "gender": true, "height": 1.65, "grade": null, "middle_school": "\"W3C\" Middle School", "skills": [ "JavaScript", "Java", "Python", "Lisp" ] }
Json parsing source code
1 /** 2 * Resolve to a list 3 * @return 4 * @throws IOException 5 * @throws JSONException 6 */ 7 private List<String> json_parser() throws IOException, JSONException { 8 List<String> lstContent = new ArrayList<String>(); 9 String data = getContent(getResources(), R.raw.test2); 10 JSONObject jsonObject = new JSONObject(data); 11 String name = jsonObject.getString("name"); 12 int age = jsonObject.getInt("age"); 13 boolean gender = jsonObject.getBoolean("gender"); 14 double height = jsonObject.getDouble("height"); 15 Object grade = jsonObject.get("grade"); 16 String middleSchool = jsonObject.getString("middle_school"); 17 JSONArray jsonArray = jsonObject.getJSONArray("skills"); 18 lstContent.add("name=" + name); 19 lstContent.add("age=" + age); 20 lstContent.add("gender=" + gender); 21 lstContent.add("height=" + height); 22 lstContent.add("grade=" + grade); 23 lstContent.add("middleSchool=" + middleSchool); 24 for (int i = 0; i < jsonArray.length(); i++) { 25 String skill = jsonArray.getString(i); 26 lstContent.add("skill=" + skill); 27 } 28 return lstContent; 29 } 30 31 /** 32 * Get the corresponding content of Json file through id 33 * @param resources 34 * @param id 35 * @return 36 * @throws IOException 37 */ 38 private String getContent(Resources resources, int id) throws IOException { 39 StringBuilder stringBuilder = new StringBuilder(); 40 InputStream inputStream = null; 41 try { 42 inputStream = resources.openRawResource(id); 43 byte[] bytes = new byte[1024]; 44 int length = inputStream.read(bytes, 0, 1024); 45 while (length > -1) { 46 stringBuilder.append(new String(bytes, 0, length)); 47 length = inputStream.read(bytes, 0, 1024); 48 } 49 } finally { 50 if (inputStream != null) { 51 inputStream.close(); 52 } 53 } 54 return stringBuilder.toString(); 55 }
Similarly, if the Json file is large or parsed slowly, it cannot be executed in the Activity main thread. A new Worker thread needs to be started and executed in the background, as follows:
1 private static final String TAG="TAG"; 2 3 private static final int MSG_FINISH=0x0001; 4 5 private static final int MSG_SERIALIZE=0x0002; 6 7 private TextView tvMsg; 8 9 private Handler handler=new Handler(){ 10 @Override 11 public void handleMessage(Message msg) { 12 switch (msg.what){ 13 case MSG_FINISH: 14 List<String> lstContent=(List<String>)msg.obj; 15 for (String info :lstContent){ 16 tvMsg.append(info+"\r\n"); 17 } 18 break; 19 } 20 } 21 }; 22 23 /** 24 * Analyzing Json 25 * @param view 26 */ 27 public void bn_json_parser_click(View view) { 28 tvMsg.setText(""); 29 new Thread() { 30 @Override 31 public void run() { 32 try { 33 List<String> lstContent = json_parser(); 34 Message msg = handler.obtainMessage(); 35 msg.what = MSG_FINISH; 36 msg.obj = lstContent; 37 handler.sendMessage(msg); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } catch (JSONException e) { 41 e.printStackTrace(); 42 } 43 } 44 }.start(); 45 }
If you need to deserialize Json into class objects, or serialize class objects into Json format files, here is a help class:
1 package com.hex.demoxml; 2 3 import android.util.Log; 4 5 import java.util.Collection; 6 import java.lang.reflect.Array; 7 import java.lang.reflect.Field; 8 import java.lang.reflect.ParameterizedType; 9 import java.lang.reflect.Type; 10 import java.util.Collection; 11 import org.json.JSONArray; 12 import org.json.JSONException; 13 import org.json.JSONObject; 14 import org.json.JSONStringer; 15 16 /** JSON Serialization Auxiliary Classes**/ 17 public class JsonHelper { 18 private static final String TAG="TAG"; 19 /** 20 * Converting objects into Json strings 21 **/ 22 public static String toJSON(Object obj) { 23 JSONStringer js = new JSONStringer(); 24 serialize(js, obj); 25 return js.toString(); 26 } 27 28 /** 29 * Serialization to JSON 30 **/ 31 private static void serialize(JSONStringer js, Object o) { 32 if (isNull(o)) { 33 try { 34 js.value(null); 35 } catch (JSONException e) { 36 e.printStackTrace(); 37 } 38 return; 39 } 40 41 Class<?> clazz = o.getClass(); 42 if (isObject(clazz)) { // object 43 serializeObject(js, o); 44 } else if (isArray(clazz)) { // array 45 serializeArray(js, o); 46 } else if (isCollection(clazz)) { // aggregate 47 Collection<?> collection = (Collection<?>) o; 48 serializeCollect(js, collection); 49 } else { // Single value 50 try { 51 js.value(o); 52 } catch (JSONException e) { 53 e.printStackTrace(); 54 } 55 } 56 } 57 58 /** 59 * Serialized arrays 60 **/ 61 private static void serializeArray(JSONStringer js, Object array) { 62 try { 63 js.array(); 64 for (int i = 0; i < Array.getLength(array); ++i) { 65 Object o = Array.get(array, i); 66 serialize(js, o); 67 } 68 js.endArray(); 69 } catch (Exception e) { 70 e.printStackTrace(); 71 } 72 } 73 74 /** 75 * Serialized set 76 **/ 77 private static void serializeCollect(JSONStringer js, Collection<?> collection) { 78 try { 79 js.array(); 80 for (Object o : collection) { 81 serialize(js, o); 82 } 83 js.endArray(); 84 } catch (Exception e) { 85 e.printStackTrace(); 86 } 87 } 88 89 /** 90 * serialized objects 91 **/ 92 private static void serializeObject(JSONStringer js, Object obj) { 93 try { 94 js.object(); 95 for (Field f : obj.getClass().getFields()) { 96 Object o = f.get(obj); 97 js.key(f.getName()); 98 serialize(js, o); 99 } 100 js.endObject(); 101 } catch (Exception e) { 102 e.printStackTrace(); 103 } 104 } 105 106 /** 107 * Deserializing Simple Objects 108 * 109 * @throws 110 **/ 111 public static <T> T parseObject(JSONObject jo, Class<T> clazz) { 112 Log.i(TAG, "parseObject: >>>>>>Second Start"); 113 if (clazz == null || isNull(jo)) { 114 Log.i(TAG, "parseObject: >>>>>>The second parseObject"); 115 return null; 116 } 117 118 T obj = createInstance(clazz); 119 if (obj == null) { 120 Log.i(TAG, "parseObject: >>>>>>Create an empty instance"); 121 return null; 122 } 123 Log.i(TAG, "parseObject: >>>>>>Attribute Length"+clazz.getFields().length); 124 Log.i(TAG, "parseObject: >>>>>>Attribute Length 2"+clazz.getClass()); 125 for (Field f : clazz.getFields()) { 126 Log.i(TAG, "parseObject: >>>>>>"+f.getName()); 127 setField(obj, f, jo); 128 //Log.i(TAG, "parseObject: >>>>>>"+obj.); 129 } 130 Log.i(TAG, "parseObject: >>>>>Return obj"+obj.getClass()); 131 return obj; 132 } 133 134 /** 135 * Deserializing Simple Objects 136 * 137 * @throws 138 **/ 139 public static <T> T parseObject(String jsonString, Class<T> clazz) { 140 if (clazz == null || jsonString == null || jsonString.length() == 0) { 141 Log.i(TAG, "parseObject: >>>>>>>null"); 142 return null; 143 } 144 Log.i(TAG, "parseObject: >>>>>>>not null"); 145 JSONObject jo = null; 146 try { 147 jo = new JSONObject(jsonString); 148 } catch (JSONException e) { 149 Log.i(TAG, "parseObject: >>>>>>Transformation json Object exception:"+e.getMessage()); 150 e.printStackTrace(); 151 } 152 153 if (isNull(jo)) { 154 Log.i(TAG, "parseObject: >>>>>After conversion to null"); 155 return null; 156 } 157 Log.i(TAG, "parseObject: >>>>>>Go to the next step"); 158 return parseObject(jo, clazz); 159 } 160 161 /** 162 * Deserializing array objects 163 * 164 * @throws 165 **/ 166 public static <T> T[] parseArray(JSONArray ja, Class<T> clazz) { 167 if (clazz == null || isNull(ja)) { 168 return null; 169 } 170 171 int len = ja.length(); 172 Log.i(TAG, "parseArray: >>>>>"+len); 173 Log.i(TAG, "parseArray: >>>>>"+clazz.getName()); 174 @SuppressWarnings("unchecked") 175 T[] array = (T[]) Array.newInstance(clazz, len); 176 177 for (int i = 0; i < len; ++i) { 178 try { 179 Object object=ja.get(i); 180 if(isSingle(clazz)){ 181 Log.i(TAG, "parseArray: >>>>>:"+object.toString()); 182 array[i]=(T)object.toString(); 183 }else { 184 JSONObject jo = ja.getJSONObject(i); 185 Log.i(TAG, "parseArray: >>>>>jo:"+jo.toString()); 186 T o = parseObject(jo, clazz); 187 Log.i(TAG, "parseArray: >>>>>o:" + o.toString()); 188 array[i] = o; 189 } 190 } catch (JSONException e) { 191 e.printStackTrace(); 192 } 193 } 194 195 return array; 196 } 197 198 /** 199 * Deserializing array objects 200 * 201 * @throws 202 **/ 203 public static <T> T[] parseArray(String jsonString, Class<T> clazz) { 204 if (clazz == null || jsonString == null || jsonString.length() == 0) { 205 return null; 206 } 207 JSONArray jo = null; 208 try { 209 jo = new JSONArray(jsonString); 210 } catch (JSONException e) { 211 e.printStackTrace(); 212 } 213 214 if (isNull(jo)) { 215 return null; 216 } 217 218 return parseArray(jo, clazz); 219 } 220 221 /** 222 * Deserialized generic sets 223 * 224 * @throws 225 **/ 226 @SuppressWarnings("unchecked") 227 public static <T> Collection<T> parseCollection(JSONArray ja, Class<?> collectionClazz, 228 Class<T> genericType) { 229 230 if (collectionClazz == null || genericType == null || isNull(ja)) { 231 return null; 232 } 233 234 Collection<T> collection = (Collection<T>) createInstance(collectionClazz); 235 236 for (int i = 0; i < ja.length(); ++i) { 237 try { 238 JSONObject jo = ja.getJSONObject(i); 239 T o = parseObject(jo, genericType); 240 collection.add(o); 241 } catch (JSONException e) { 242 e.printStackTrace(); 243 } 244 } 245 246 return collection; 247 } 248 249 /** 250 * Deserialized generic sets 251 * 252 * @throws 253 **/ 254 public static <T> Collection<T> parseCollection(String jsonString, Class<?> collectionClazz, 255 Class<T> genericType) { 256 if (collectionClazz == null || genericType == null || jsonString == null 257 || jsonString.length() == 0) { 258 return null; 259 } 260 JSONArray jo = null; 261 try { 262 jo = new JSONArray(jsonString); 263 } catch (JSONException e) { 264 e.printStackTrace(); 265 } 266 267 if (isNull(jo)) { 268 return null; 269 } 270 271 return parseCollection(jo, collectionClazz, genericType); 272 } 273 274 /** 275 * Create objects by type 276 **/ 277 private static <T> T createInstance(Class<T> clazz) { 278 if (clazz == null) 279 return null; 280 T obj = null; 281 try { 282 obj = clazz.newInstance(); 283 } catch (Exception e) { 284 Log.i(TAG, "createInstance: >>>>>>Create instance exceptions"); 285 e.printStackTrace(); 286 } 287 return obj; 288 } 289 290 /** 291 * Set the value of the field 292 **/ 293 private static void setField(Object obj, Field f, JSONObject jo) { 294 String name = f.getName(); 295 Class<?> clazz = f.getType(); 296 Log.i(TAG, "setField: >>>>>name:"+name); 297 try { 298 if (isArray(clazz)) { // array 299 Log.i(TAG, "setField: >>>>>array"); 300 Class<?> c = clazz.getComponentType(); 301 JSONArray ja = jo.optJSONArray(name); 302 if (!isNull(ja)) { 303 Log.i(TAG, "setField: >>>>>ja:"+ja.getString(0)); 304 Object array = parseArray(ja, c); 305 f.set(obj, array); 306 }else{ 307 Log.i(TAG, "setField: >>>>>The array is empty"); 308 } 309 } else if (isCollection(clazz)) { // Generic sets 310 Log.i(TAG, "setField: >>>>>Generic sets"); 311 // Gets the generic type defined 312 Class<?> c = null; 313 Type gType = f.getGenericType(); 314 if (gType instanceof ParameterizedType) { 315 ParameterizedType ptype = (ParameterizedType) gType; 316 Type[] targs = ptype.getActualTypeArguments(); 317 if (targs != null && targs.length > 0) { 318 Type t = targs[0]; 319 c = (Class<?>) t; 320 } 321 } 322 323 JSONArray ja = jo.optJSONArray(name); 324 if (!isNull(ja)) { 325 Object o = parseCollection(ja, clazz, c); 326 f.set(obj, o); 327 } 328 } else if (isSingle(clazz)) { // Value type 329 Log.i(TAG, "setField: >>>>>Single Value type"); 330 Object o = jo.opt(name); 331 if (o != null) { 332 f.set(obj, o); 333 } 334 } else if (isObject(clazz)) { // object 335 Log.i(TAG, "setField: >>>>>Object object:"+clazz); 336 JSONObject j = jo.optJSONObject(name); 337 if (!isNull(j)) { 338 339 Object o = parseObject(j, clazz); 340 f.set(obj, o); 341 }else{ 342 Log.i(TAG, "setField: >>>>>Object Objects are null"); 343 } 344 } else { 345 Log.i(TAG, "setField: >>>>>unknown type:"+clazz); 346 throw new Exception("unknow type!"); 347 } 348 } catch (Exception e) { 349 e.printStackTrace(); 350 } 351 } 352 353 /** 354 * Judging whether the object is empty 355 **/ 356 private static boolean isNull(Object obj) { 357 if (obj instanceof JSONObject) { 358 return JSONObject.NULL.equals(obj); 359 } 360 return obj == null; 361 } 362 363 /** 364 * Determine whether it is a value type 365 **/ 366 private static boolean isSingle(Class<?> clazz) { 367 return isBoolean(clazz) || isNumber(clazz) || isString(clazz); 368 } 369 370 /** 371 * Whether Boolean Value or not 372 **/ 373 public static boolean isBoolean(Class<?> clazz) { 374 return (clazz != null) 375 && ((Boolean.TYPE.isAssignableFrom(clazz)) || (Boolean.class 376 .isAssignableFrom(clazz))); 377 } 378 379 /** 380 * Is it numeric? 381 **/ 382 public static boolean isNumber(Class<?> clazz) { 383 return (clazz != null) 384 && ((Byte.TYPE.isAssignableFrom(clazz)) || (Short.TYPE.isAssignableFrom(clazz)) 385 || (Integer.TYPE.isAssignableFrom(clazz)) 386 || (Long.TYPE.isAssignableFrom(clazz)) 387 || (Float.TYPE.isAssignableFrom(clazz)) 388 || (Double.TYPE.isAssignableFrom(clazz)) || (Number.class 389 .isAssignableFrom(clazz))); 390 } 391 392 /** 393 * Determine whether it's a string or not 394 **/ 395 public static boolean isString(Class<?> clazz) { 396 return (clazz != null) 397 && ((String.class.isAssignableFrom(clazz)) 398 || (Character.TYPE.isAssignableFrom(clazz)) || (Character.class 399 .isAssignableFrom(clazz))); 400 } 401 402 /** 403 * Judging whether it is an object 404 **/ 405 private static boolean isObject(Class<?> clazz) { 406 return clazz != null && !isSingle(clazz) && !isArray(clazz) && !isCollection(clazz); 407 } 408 409 /** 410 * Determine whether it is an array 411 **/ 412 public static boolean isArray(Class<?> clazz) { 413 return clazz != null && clazz.isArray(); 414 } 415 416 /** 417 * Judging whether it is a set 418 **/ 419 public static boolean isCollection(Class<?> clazz) { 420 return clazz != null && Collection.class.isAssignableFrom(clazz); 421 } 422 }
Remarks
Thousands of sails passed by the side of the sunken boat, and ten thousand trees and springs ahead of the sick tree.