Android-- analysis of XML SAX

Preface

  Since the XML analysis, the first to talk about what is XML. XML, Extensible markup language (Extensible Markup Language), used to mark the electronic file which has structural markup language, can be used to tag data, the data type is defined, is a allows the user to define their markup language for the source language, this is Baidu Baike explanation. XML is a common format for transmitting data in Internet, and HTML, are SGML (Standard Generalized Markup Language), whether you need to access the data through the Internet, or send data to a Web service, may need to use the knowledge of XML. On the Android application requirements and network interaction, or just a single non interactive applications, so it is possible to use XML in Android application development.

  Due to the expansion of XML, so it need to have basic rules of stability to support the expansion, the grammatical rules need to pay attention to is:

  1. The start and end tags matching.
  2. Nested tags cannot be nested.
  3. Case sensitive.

In Android XML

  Android platform is the biggest advantage, the application can use the Java programming language development, Java platform to use XML in many different ways, and the majority of XML related API has in the Android system has been fully support. But because of the limitations of the Android device, generally only consider three ways of parsing XML:

  1. DOM, Document Object Model, The document object model, analytic completion of XML will generate objects in a tree structure.
  2. SAX, simple API for  Xml, To notify the program events, analysis of the XML.
  3. XML PULL, Similar to the SAX mode, program to pull way to parse the XML.

SAX

  SAX is an event driven XML API, XML structure, can be specified to process special from the parser code by its definition of event streams in simple terms, it is the analytical speed, less memory connected with the parser, the parser for Android and other mobile devices.

  The advantages of using SAX:

  Because of the advantage of SAX is the stream processing mode, when a tag is encountered, and never before encountered record label. That is to say, will trigger read at each node of the startElement () method, can know the information, only names and attributes of the current signature, as far as the structure of nested tag, the tag name, whether the information element is associated with other structures, is not know.

  

  Simple steps using SAX analysis XML:

  1. A new kind of MyHandler, inherited from DefaultHandler, override the DefaultHandler method and characteristic of XML, analytical work in this category.
  2. Instantiate a SAX parser factory object, SAXParserFactory object, using the SAXParserFactory.newInstance () method to obtain the.
  3. Using SAXParserFactory.newSAXParser (SAXParser) SAX parser object.
  4. The instantiation of class MyHandler, incoming name node needs analysis.
  5. Use the SAXParser.parse () method is provided for parsing XML flow and XML analytic objects.
  6. Finally, the analytical results obtained from the MyHandler object.

  Now, explain in detail the above mentioned types of roles.

  The DefaultHandler class is the base class SAX2 the default event handler. It is inherited from the EntityResolver, DTDHandler, ContentHandler and ErrorHandler four interface. Contains all the methods of the four interface, so we write event handlers, can not directly to achieve the four interface, and extend this class, then we need to override the method.

  In DefaultHandler inheriting classes, specific methods need to rewrite the following:

  Some of the above rewriting method to explain when executed by a XML file.

<?xml version="1.0" encoding="utf-8"?>

startDocument

<persons>

startElement

 <person id="23">

startElement

  <name nameid="1">

startElement

Jack

characters

  </name>

endElement

  <age>

startElement

21

characters

  </age>

endElement

 </person>                     endElement       

</persons>                     endElement

  The SAXParserFactory class, the definition of a factory in API, enable the application to configure and obtain the SAX based parser to parse the XML document. It is only a method of constructing prctected (single mode), so we need to use the static newInstance () method and SAXParserFactory (object). The use of SAXParserFactory can call.NewSAXParser () method to obtain a SAXParser, can be performed through the SAXParser object (parser) method, set the XML flow and the parser class by passing parameters.

Sample program

  Now through a sample program to explain SAX is how to parse XML file, the example program is running on the Android platform, in order to simulate the real situation, placed a static XML file on the IIS server, using Android program to read the contents of the XML file, in this sample program, read the person values of nodes. Because of the Android program, so don't forget to give it permission to access the network.

  The contents of the XML file:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <persons>
 3 <person id="23">
 4 <name nameid="1">Jack</name>
 5 <age>21</age>
 6 </person>
 7 <person id="20">
 8 <name nameid="2">Dick</name>
 9 <age>23</age>
10 </person>
11 </persons>

  Step 1, the DefaultHandler class inheritance sub class MyHandler:

 1 package cn.bgxt.handler;
 2 
 3 import java.util.ArrayList;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 
 7 import org.xml.sax.Attributes;
 8 import org.xml.sax.SAXException;
 9 import org.xml.sax.helpers.DefaultHandler;
10 
11 public class MyHandler extends DefaultHandler {
12 
13     private List<HashMap<String, String>> list = null; //Analysis of XML content after
14     private HashMap<String, String> map = null;  //XML content store currently need to record node
15     private String currentTag = null;//XML nodes of the current read
16     private String currentValue = null;//The text of the XML value of the current node
17     private String nodeName = null;//To parse the node name
18 
19     public MyHandler(String nodeName) {
20         // Set the resolution node name
21         this.nodeName = nodeName;
22     }
23 
24     @Override
25     public void startDocument() throws SAXException {
26         // Receive notification of the document to start. 
27         // Instantiate a ArrayList for storing XML data analysis
28         list = new ArrayList<HashMap<String, String>>();
29     }
30 
31     @Override
32     public void startElement(String uri, String localName, String qName,
33             Attributes attributes) throws SAXException {
34         // Inform the receiving element to start.         
35         if (qName.equals(nodeName)) {
36             //If the name node of the current operation and setting need to read the node names are the same, then instantiate HashMap
37             map = new HashMap<String, String>();
38         }
39         //Attributes as the attribute value of the current node, if the existence of attribute value, attribute value is read. 
40         if (attributes != null && map != null) {
41             for (int i = 0; i <attributes.getLength(); i++) {
42                 //Read attributes to values, insert into Map. 
43                 map.put(attributes.getQName(i), attributes.getValue(i));
44             }
45         }
46         //Record the name of the current node. 
47         currentTag = qName;
48     }
49 
50     @Override
51     public void characters(char[] ch, int start, int length)
52             throws SAXException {
53         // Notice the character data receiving element in the. 
54         //The current node has value in case before continuing execution
55         if (currentTag != null && map != null) {
56             //Gets the text value of the current node, the text ch the array is stored value. 
57             currentValue = new String(ch, start, length);
58             if (currentValue != null && !currentValue.equals("")
59                     && !currentValue.equals("\n")) {
60                 //Read the text to judge cannot be null, not equal to ” “, not equal to”\n“
61                 map.put(currentTag, currentValue);
62             }
63         }
64         //Reading is completed, need to clear the current node label value and contains the text value. 
65         currentTag = null;
66         currentValue = null;
67     }
68 
69     @Override
70     public void endElement(String uri, String localName, String qName)
71             throws SAXException {
72         // Inform the receiving element end. 
73         if (qName.equals(nodeName)) {
74             //If the read with node is we need to pay attention to, then add map to the list preservation
75             list.add(map);
76             //Using empty map, started to read a new round of person. 
77             map = null;
78         }
79     }
80 
81     public List<HashMap<String, String>> getList() {
82         return list;
83     }
84 
85 }

  Because the XML file is placed on the server, need to write a HttpUitils class to read the XML file on the server, read the URLHttpConnection mode is used, if you don't know URLHttpConnection friends, can see the previous blog:. The following code directly attached:

 1 package cn.bgxt.http;
 2 
 3 import java.io.InputStream;
 4 import java.net.HttpURLConnection;
 5 import java.net.URL;
 6 
 7 public class HttpUtils {
 8 
 9     public HttpUtils() {
10     }
11     public static InputStream getXML(String path) {
12         try {
13             URL url=new URL(path);
14             if(url!=null)
15             {
16                 HttpURLConnection connection=(HttpURLConnection)url.openConnection();
17                 connection.setDoInput(true);
18                 connection.setConnectTimeout(3000);
19                 connection.setRequestMethod("GET");
20                 int requesetCode=connection.getResponseCode();
21                 if(requesetCode==200)
22                 {
23                     //If successfully implemented, return to the HTTP response stream
24                     return connection.getInputStream();
25                 }
26             }
27         } catch (Exception e) {
28             // TODO: handle exception
29         }        
30         return null;
31     }
32 }

  Also need a call to the SAXParser object class, here a new class SaxService, instantiate the SAXParserFactory used to set the XML flow and the parser. The following code:

 1 package cn.bgxt.service;
 2 
 3 import java.io.InputStream;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 
 7 import javax.xml.parsers.SAXParser;
 8 import javax.xml.parsers.SAXParserFactory;
 9 
10 import cn.bgxt.handler.MyHandler;
11 
12 public class SaxService {
13 
14     public SaxService() {
15         // TODO Auto-generated constructor stub
16     }
17     
18     public static List<HashMap<String, String>> readXML(InputStream inputStream,String nodeName)
19     {
20         try {
21             //Instantiate a SAX factory
22             SAXParserFactory factory=SAXParserFactory.newInstance();
23             //Instantiate a SAX parser. 
24             SAXParser sParser=factory.newSAXParser();
25             //To instantiate DefaultHandler, node settings need to be resolved
26             MyHandler myHandler=new MyHandler(nodeName);
27             // To parse
28             sParser.parse(inputStream, myHandler);
29             // Analysis is completed, close the stream
30             inputStream.close();
31             //Returns the analytical results. 
32             return myHandler.getList();
33         } catch (Exception e) {
34             // TODO: handle exception
35         }        
36         return null;
37     }
38     
39 }

 Finally, Android is a Activity class, the layout of the interface is very simple, only one button controls, there is no display layout code. The click of a button, triggering the click event, because it is Android4.0+, so I can't access the network in the main thread, need another thread, it uses the Thread class. The following code:  

  

 1 package cn.bgxt.androidxmlforsax;
 2 
 3 import java.io.InputStream;
 4 import java.util.HashMap;
 5 import java.util.List;
 6 import cn.bgxt.http.HttpUtils;
 7 import cn.bgxt.service.SaxService;
 8 import android.os.Bundle;
 9 import android.app.Activity;
10 import android.view.Menu;
11 import android.view.View;
12 import android.widget.Button;
13 
14 public class MainActivity extends Activity {
15     private Button btn;
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_main);
20         
21         btn=(Button)findViewById(R.id.btn);
22         btn.setOnClickListener(new View.OnClickListener() {
23             
24             @Override
25             public void onClick(View v) {
26                 //Android4.0+ requires a separate thread access network
27                 Thread thread=new Thread(new Runnable() {
28                     
29                     @Override
30                     public void run() {
31                         // Set the location of the XML document
32                         String path="http://192.168.1.107:1231/persons.xml";
33                         //Read XML on the server, access to XML flow
34                         InputStream inputStream=HttpUtils.getXML(path);
35                         try {
36                             //The analytical flow, nodes need to be resolved
37                             List<HashMap<String, String>> list=SaxService.readXML(inputStream, "person");
38                             for(HashMap<String,String> map:list)
39                             {
40                                 //Print to LogCat
41                                 System.out.println(map.toString());
42                             }
43                         } catch (Exception e) {
44                             // TODO: handle exception
45                         }
46                     }
47                 });
48                 thread.start();                
49             }
50         });        
51     }
52 
53     @Override
54     public boolean onCreateOptionsMenu(Menu menu) {
55         // Inflate the menu; this adds items to the action bar if it is present.
56         getMenuInflater().inflate(R.menu.main, menu);
57         return true;
58     }
59 
60 }

   When clicked, the XML parsed content print to log in, you can use the LogCat to view.

  Download the source code 

  

  

  

Posted by Brant at November 21, 2013 - 1:10 PM