Android series--dom, SAX, pull parsing xml

Source: Internet
Author: User
Tags cdata closing tag xml parser

One, Dom parsing xml

We first look at the DOM (Document Object Model) parsing XML, through the DOM parsing XML in the development of the Java EE is very common, it is the entire XML as a tree-like structure, when parsing, the entire XML file will be loaded into our memory, We then parse our XML data through the API provided by the DOM, which is very convenient for parsing XML, and we can access it through a node to its sibling or to the parent class, the child class node. So what are the steps to parsing XML through the DOM?

1. First, through the Documentbuilderfactory class to build a parse factory class, through the Newinstance () method can get a Documentbuilderfactory object.

2. Create a Documentbuilder object from the factory class above, which is used to parse our XML document through the Documentbuilderfactory Newdocumentbuilder () method

3. By creating the Parse (InputStream) method of the Documentbuilder object, we can parse our XML document and return a Document object that represents our entire XML document.

4. Once the document object for the entire XML is obtained, we can get the element nodes below it, as well as each element node may have more than one attribute (Attribute), depending on each element node, we can traverse the child nodes under the element node and so on.

To illustrate here, in the DOM API, node, which represents the original data type of our entire DOM object, represents each single node in the entire document tree. All objects that implement node's interface can handle their child nodes, and of course, not every node has children, such as Textnode (text node), through node's nodeName, NodeValue, attributes three properties, We can easily get each node node name, node value, node properties, and so on, let's look at the different types of node nodes its nodename, nodevalue, attributes three attributes represent what:

Interface NodeName NodeValue attributes
Attr Same asAttr.name Same asAttr.value null
CDATASection "#cdata-section" Same CharacterData.data as, the content of the CDATA section null
Comment "#comment" Same CharacterData.data as, the content of the comment null
Document "#document" null null
DocumentFragment "#document-fragment" null null
DocumentType Same asDocumentType.name null null
Element Same asElement.tagName null NamedNodeMap
Entity Entity Name null null
EntityReference Name of entity referenced null null
Notation notation Name null null
ProcessingInstruction Same asProcessingInstruction.target Same asProcessingInstruction.data null
Text "#text" Same CharacterData.data as, the content of the text node null

In fact, the most we used is the element and text, through the element of the NodeName property can get the label name of the node, the text object of the NodeValue to get the elements of the node text value content, Let's take a look at a code case that parses XML through the DOM:

First we build an XML document, which will be placed on our server, the HTTP protocol to get this XML document, and then on our Android client to parse it

<?xml version= "1.0" encoding= "UTF-8"?><persons>    <person id= "1" >        <name> Little Luo </name >        <age>21</age>    </person>    <person id= "2" >        <name>android</ name>        <age>15</age>    </person></persons>

Let's look at the tool class for DOM parsing server-side xml:

public class domparserutils{public static list<person> parserxmlbydom (InputStream inputstream) throws Exception        {list<person> persons = new arraylist<person> ();        Get a documentbuilderfactory parse factory class Documentbuilderfactory factory = Documentbuilderfactory.newinstance ();        Get a Documentbuilder parsing class Documentbuilder builder = Factory.newdocumentbuilder ();        Receives an XML string to parse the xml,document representing the entire XML document file document = Builder.parse (InputStream);        The root element node of the XML document is obtained as Personselement = Document.getdocumentelement ();        Gets the collection of node objects labeled Person NodeList NodeList NodeList = personselement.getelementsbytagname ("person");            for (int i = 0; i < nodelist.getlength (); i++) {Person person = new person ();                If the NODE is an ELEMENT if (Nodelist.item (i). Getnodetype () = = Document.element_node) { Element personelement = (Element)Nodelist.item (i);                Gets the attribute value of the id String id = personelement.getattribute ("id");                                Person.setid (Integer.parseint (id));                Get the child element under the person element NodeList childnodeslist = Personelement.getchildnodes (); for (int j = 0; J < Childnodeslist.getlength (); j + +) {if (Childnodeslist.item (j). Getno                        Detype () = = Document.element_node) {//resolves to the name tag under person if ("Name". Equals (Childnodeslist.item (j). Getnodename ())) {//Get                            The literal value of the name label is String name = Childnodeslist.item (j). Getfirstchild (). Getnodevalue ();                        Person.setname (name);                            } else if ("Address". Equals (Childnodeslist.item (j). Getnodename ())) { String age = CHildnodeslist.item (j). Getfirstchild (). Getnodevalue ();                        Person.setage (Integer.parseint (age));                }}} persons.add (person);            person = null;    }} return persons; }}

The advantage of parsing XML through DOM is that we can access the neighboring nodes of a node at any time, and the insertion of the XML document is also very convenient, the downside is that it will load the entire XML document into memory, which will greatly occupy our memory resources, for the mobile phone, Memory resources are very valuable, so in the mobile phone, through the DOM this way to parse the XML is relatively small.

Second, SAX parsing xml

Sax (simple API for XML), then let's look at another way of parsing XML that parses XML documents through sax.

Sax is a fast parsing and memory-intensive XML parser that is ideal for mobile devices such as Android. The Sax parsing XML file is event-driven, that is, it does not need to parse the entire document, and in the process of parsing the document in order of content, Sax determines whether the currently read character is a part of the valid XML syntax, and triggers the event if it conforms. The so-called events are actually some callback (callback) methods, which are defined in the ContentHandler interface. Here are some common methods for ContentHandler interfaces:

Startdocument () Call this method when it encounters the beginning of the document, where you can do some preprocessing work. Enddocument () corresponds to the above method, which, when the document is finished, calls this approach, where you can do some cleanup work. Startelement (String NamespaceURI, String LocalName, String qName, Attributes Atts) This method is triggered when a start tag is read. NamespaceURI is a namespace, LocalName is a label name without a namespace prefix, and QName is a label name with a namespace prefix. All property names and corresponding values can be obtained by Atts. Note that one of the important features of Sax is its streaming, when it encounters a tag, it does not record the tags that were encountered before, that is, in the Startelement () method, all the information you know is the name and attributes of the tag, as for the nested structure of the tag, The name of the upper label, whether there is a sub-genus and other information related to the structure, are not known, all need your program to complete. This makes sax less convenient for programming without DOM. EndElement (String uri, String localname, String name) This method corresponds to the above approach, which is called when the closing tag is encountered. Characters (char[] ch, int start, int length) This method is used to process the content read in the XML file, the first parameter is used to hold the contents of the file, and the next two parameters are the starting position and length of the string to be read in the array, using the new String (ch,start,length) to get the content.

It is important to note that Sax parsing XML is based on the processing of event streams, so each parsing to a tag does not record the information before the tag, and we only know the name of the current expression and its properties, and as for the nesting of tags, the names of the upper tags are not known.

The most important step in Sax parsing XML is to define our own handler processing class, and we can let it inherit the DefaultHandler class, and then rewrite its callback method inside to do our XML parsing in these callback methods.

Let's look at an example to see if parsing XML through sax first defines our own handler class:

public class MyHandler extends defaulthandler{private list<person> persons;    private person person;    Stores the currently parsed tag name private String Currenttag;        The text value of the label currently parsed to the private String currentvalue;    Public list<person> getpersons () {return persons; }//When parsing to the beginning of the document, the callback method @Override public void Startdocument () throws saxexception {persons = new Ar    Raylist<person> ();            }//When parsing a label to XML, the callback method @Override public void Startelement (string uri, String localname, String qName, Attributes Attributes) throws Saxexception {if (' person '. Equals (QName)) {person = new P            Erson (); Gets the property value of the current element for (int i = 0; i < attributes.getlength (); i++) {if ("id". Equals (                Attributes.getqname (i))) {Person.setid (Integer.parseint (Attributes.getvalue (i)));  }            }        }        //  Sets the current label name currenttag = QName; }//When parsing to XML text content, the callback method @Override public void characters (char[] ch, int start, int length) thro        WS Saxexception {//Gets the current text content CurrentValue = new String (ch,start, length); When CurrentValue is not null, "" and if the line wraps if (currentvalue! = null &&! "). Equals (CurrentValue) &&! "            \ n ". Equals (CurrentValue)) {//To determine which label of the current Currenttag is the IF (" Name ". Equals (Currenttag))            {person.setname (CurrentValue);            } else if ("Age". Equals (Currenttag)) {Person.setage (Integer.parseint (CurrentValue));        }}//emptying Currenttag and currentvalue currenttag = null;    CurrentValue = null;            }//When parsing to the end of the label, the callback method @Override public void EndElement (string uri, String localname, String qName)     Throws Saxexception {if ("person". Equals (QName)) {       Persons.add (person);        person = null; }    }}

Then look at the Util class for sax parsing xml:

public class saxparserutils{public    static list<person> Parserxmlbysax (InputStream inputstream) throws Exception    {        //    Create a saxparserfactory resolution factory class        SAXParserFactory factory = saxparserfactory.newinstance ( );    instantiate a SAXParser parsing class        SAXParser parser = Factory.newsaxparser ();    Instantiate our MyHandler class        MyHandler MyHandler = new MyHandler ();    parse the XML document        Parser.parse (InputStream, MyHandler) According to our custom handler;        return myhandler.getpersons ();    }}

Third, pull parse xml

Finally, we introduce the third way of parsing XML, pull. Pull parsing is similar to sax parsing, which is based on the event stream, which comes with a pull-resolved jar package in Android, so we don't need to import a third-party jar package.

The difference between the pull parser and the SAX parser:

The pull parser and SAX parser are different but have similarities. The difference is that the SAX parser works by automatically pushing events into the registered event handler, so you can't control the active end of event handling;

The pull parser works by allowing your application code to proactively get events from the parser, because it is an active fetch event, so you can no longer get the event after the desired condition has been met, ending the parsing. This is the main difference between them.

And their similarity in the run mode, the pull parser also provides events similar to sax (starting document Start_document and ending document End_document, starting element Start_tag and ending element End_tag, encountering element content text, etc.), But you need to call the next () method to extract them (extract events proactively).

The package associated with the Pull method in the Android system is ORG.XMLPULL.V1, which provides the factory class xmlpullparserfactory of the pull parser and the pull parser xmlpullparser,xmlpullparserfactory instance tuning The Newpullparser method is used to create the Xmlpullparser parser instance, and then the Xmlpullparser instance can invoke Geteventtype () and Next () to extract the event sequentially. and the corresponding logical processing according to the type of event extracted.

Let's take a look at the steps of pull parsing XML through a code:

public class pullparserutils{public static list<person> Parserxmlbypull (InputStream inputstream) throws Exceptio        n {list<person> persons = null;                person person = null;        Create Xmlpullparserfactory resolution factory Xmlpullparserfactory factory = Xmlpullparserfactory.newinstance ();        Instantiate a Xmlpullparser parsing class xmlpullparser parser = Factory.newpullparser () through the Xmlpullparserfactory factory class;                Parses the XML document Parser.setinput (InputStream, "Utf-8") according to the specified encoding;        Get the current event type int eventtype = Parser.geteventtype ();            The while (eventtype! = xmlpullparser.end_document) {switch (EventType) is parsed as long as the document ends without parsing to XML {//parsing to the beginning of the document case XmlPullParser.START_DOCUMENT:persons                = new Arraylist<person> ();                Break When parsing to XML tags, case XmlPullParser.START_TAG:if ("perSon ". Equals (Parser.getname ())) {person = new person ();                     Get the first attribute of the person element, which is the ID Person.setid (integer.parseint (parser.getattributevalue (0)));                         } else if ("name". Equals (Parser.getname ())) {                     If the name element, the value of the element Person.setname (Parser.nexttext ()) is obtained through the Nexttext () method; } else if ("Age". Equals (Parser.getname ())) {Person.setage (                     Integer.parseint (Parser.nexttext ()));                } break;                     Resolves to the end of the XML tag case XmlPullParser.END_TAG:if ("person". Equals (Parser.getname ()))                         {Persons.add (person);                     person = null;            } break; }            //    The next event is triggered by the next () method EventType = Parser.next ();    } return persons; }}

Finally, we'll write a httputils class to access our server-side XML document:

public class httputils{public    static InputStream HttpMethod (string path, string encode)    {        HttpClient HttpClient = new Defaulthttpclient ();                Try        {            HttpPost httppost = new HttpPost (path);            HttpResponse HttpResponse = Httpclient.execute (httppost);            if (Httpresponse.getstatusline (). Getstatuscode () = = Httpstatus.sc_ok)            {                httpentity httpentity = Httpresponse.getentity ();                return httpentity.getcontent ();            }        }        catch (Exception e)        {            e.printstacktrace ();        }        Finally        {            httpclient.getconnectionmanager (). shutdown ();        }                return null;}    }

Finally, take a look at the layout files for our Android application and the code for the Activity class:

public class Mainactivity extends activity{private button button;    Private Button button2;    Private Button Button3;    Private final String PATH = "Http://172.25.152.34:8080/httptest/person.xml";        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);                Setcontentview (R.layout.activity_main);        Button = (button) Findviewbyid (R.id.button1);        Button2 = (Button) Findviewbyid (R.id.button2);                Button3 = (Button) Findviewbyid (R.id.button3);        Buttononclicklistener listener = new Buttononclicklistener ();        Button.setonclicklistener (listener);        Button2.setonclicklistener (listener);    Button3.setonclicklistener (listener);        } class Buttononclicklistener implements Onclicklistener {@Override public void OnClick (View v)            {button button = (button) v;     Switch (Button.getid ()) {case R.id.button1:               Start a new thread parsing XML class MyThread1 extends thread { @Override public void Run () {InputStream I                            Nputstream = Httputils.httpmethod (PATH, "utf-8");                            list<person> persons = NULL;                            try {persons = Domparserutils.parserxmlbydom (InputStream);                                } catch (Exception e) {                            E.printstacktrace ();                        } System.out.println ("Dom--->>" + persons);                }} new MyThread1 (). Start ();                Break    Case R.id.button2://Start a new thread parsing XML class MyThread2 extends thread                {@Override public void run () {                            InputStream InputStream = Httputils.httpmethod (PATH, "utf-8");                            list<person> persons = NULL;                            try {persons = Saxparserutils.parserxmlbysax (InputStream);                                } catch (Exception e) {                            E.printstacktrace ();                        } System.out.println ("Sax--->>" + persons);                }} new MyThread2 (). Start ();                Break                    Case R.ID.BUTTON3://Start a new thread parsing XML class MyThread3 extends thread {@Override public void RUn () {InputStream InputStream = Httputils.httpmethod (PATH, "utf-8");                            list<person> persons = NULL;                            try {persons = Pullparserutils.parserxmlbypull (InputStream);                                } catch (Exception e) {                            E.printstacktrace ();                        } System.out.println ("Pull:--->>" + persons);                }} new MyThread3 (). Start ();            Break }}} @Override public boolean Oncreateoptionsmenu (Menu menu) {getmenuinflater (). Inflate (R.menu        . Main, menu);    return true; }}

Finally, let's take a look at the console output:

Summary : DOM parsing XML is relatively simple and can be accessed by sibling elements, but the entire XML document needs to be loaded into memory, and for Android devices it is not recommended to parse the XML in the same way as the DOM.

Sax and pull are event-driven XML parsers that, when parsing XML, do not load the entire XML document and consume less memory, so it is recommended that you use Sax or pull to parse the XML document in Android development.

Android series--dom, SAX, pull parsing xml

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.