Android simplifies XML sax parsing

Source: Internet
Author: User

Dom parsing takes up a lot of memory (I need to parse a variety of KML files, sometimes the 4-5m KML file uses the DOM to parse a lot of phones out of memory), and we need to introduce a third-party library, so it's a good choice to use a sax parsing that saves lots of memory and does not need to introduce other libraries. Because Sax is particularly troublesome in parsing complex XML files, it organizes a tool that simplifies the parsing of Android Sax.

Implementation idea: As with the Android touch event delivery mechanism, the node that needs to parse the sub-parser is passed down.

If there is a further simplification of the method, Welcome to Exchange! Email:[email protected].

Example program: Https://github.com/John-Chen/EasySaxParser

Simplified tool SAXParser:

Public abstract class SAXParser {protected String curqname;    protected StringBuilder Curvalue = new StringBuilder ();    protected SAXParser SAXParser;    protected String saxparserqname;    /** * required to generate the node name for sub-SAXParser */protected hashset<string> childparserqnames; Public SAXParser () {} public SAXParser (hashset<string> childparserqnames) {this.childparserqnames = c    Hildparserqnames; } protected void Startelement (String uri, String localname, String qName, Attributes Attributes) {if (QName = = N        ull) {return;        } if (SAXParser! = null) {saxparser.startelement (URI, QName, qName, attributes); }else if (childparserqnames! = null && childparserqnames.contains (qName)) {this.saxparser = Dispatchto (q            Name, attributes);                if (this.saxparser! = null) {this.saxparserqname = QName;            Saxparser.parserstart (attributes);        }}else{    Curqname = QName;            if (curvalue.length () > 0) {curvalue.delete (0, Curvalue.length ());            }}} protected void EndElement (String uri, String localname, String qName) {if (qName = = null) {        Return            } if (Qname.equals (saxparserqname)) {if (saxparser! = null) {saxparser.parserend ();            } saxparser = null;        Saxparserqname = null;        }else if (saxparser! = null) {saxparser.endelement (URI, QName, QName);            }else{parserelementend (QName, curvalue.tostring ());            Curqname = null;            if (curvalue.length () > 0) {curvalue.delete (0, Curvalue.length ());            }}} protected void characters (char[] ch, int start, int length) {if (saxparser! = null) {        Saxparser.characters (CH, start, length);            }else{String data = new String (ch, start, length); IF (data.length () > 0 && curqname! = null) {curvalue.append (data);  }}}/** * begins parsing an input stream * @param is file input stream * @param rootparserqname resolved file root node * @param rootparser                             Root parser */public static void Start (InputStream is, final String rootparserqname, Final SAXParser Rootparser) {try {saxparser parser = saxparserfactory.newinstance (            ). Newsaxparser ();  Parser.parse (IS, new DefaultHandler () {@Override public void startelement (string uri, string                        LocalName, String qName, Attributes Attributes) throws Saxexception {if (qName = = null) {                    Return } if (Rootparser! = null) {rootparser.startelement (URI, QName, qName, attributes)                    ; }else if (qname.equals (Rootparserqname)) {Rootparser.parsErstart (attributes);  }} @Override public void characters (char[] ch, int start, int length) throws saxexception {if (rootparser! = null) {rootparser.characters (ch, start, length)                    ; }} @Override public void EndElement (string uri, String localname, String qNa                    Me) throws Saxexception {if (qName = = null) {return;                            } if (Qname.contains (rootparserqname)) {if (Rootparser! = null) {                        Rootparser.parserend ();                    }}else if (rootparser! = null) {rootparser.endelement (URI, QName, QName);        }                }            });        } catch (Exception e) {e.printstacktrace ();     }    }/** * Node parsing begins */public abstract void Parserstart (Attributes Attributes);  /** * End of a child node resolution * @param value characters obtained values */public abstract void Parserelementend (String qName, String    Value); /** * Parsing events need to be passed down, returning the child SAXParser */public abstract SAXParser Dispatchto (String qName, Attributes Attributes) that need to be passed    ; /** * Node parsing end */public abstract void Parserend ();}

XML file Test.xml to parse:

<?xml version= "1.0" encoding= "UTF-8"? ><kml xmlns:gx= "http://www.google.com/kml/ext/2.2" >  < Document id= "123" >    <description>abc</description>    <author>csq</author>    <ExtendedData>      <data name= "TrackID" >        <value>293156</value>      </Data>      <data name= "Tracktypeid" >        <value>8</value>      </Data>    </extendeddata >    <Placemark>      <name> Shenzhen Bay Park </name>      <TimeStamp>        <when> 2015-03-21t10:00:13z</when>      </TimeStamp>      <Point>        <coordinates> 113.93946,22.48955,9.0</coordinates>      </Point>    </Placemark>  </Document> </kml>

   

Start parsing:

Root node kml, root node resolver kmlparser

Saxparser.start (Getassets (). Open ("TEST.KML"), "KML", New Kml.kmlparser (KML));

Partial node resolution implementation:

public static class Kmlparser extends SAXParser {        private kml kml;        Public Kmlparser (KML kml) {            super (new hashset<string> ());            THIS.KML = KML;            Childparserqnames.add ("Document");        }        @Override public void        Parserstart (Attributes Attributes) {        }        @Override public        void Parserelementend (String qName, String value) {        }        @Override public        saxparser Dispatchto (String qName, Attributes Attributes) {            if (qname.equals ("Document")) {                return new Document.documentparser (KML);            }            return null;        }        @Override public        void Parserend () {        }    }

  

public static class Documentparser extends SAXParser {private KML kml;        Private document document;            Public Documentparser (KML KML) {super (New hashset<string> ());            THIS.KML = KML;            Childparserqnames.add ("Extendeddata");        Childparserqnames.add ("Placemark");            } @Override public void Parserstart (Attributes Attributes) {document = new document ();        Document.ID = Attributes.getvalue ("id");                } @Override public void Parserelementend (string qName, String value) {if (document = = NULL) {            Return            } if (Qname.equals ("description")) {document.description = value;            }else if (qname.equals ("author")) {document.author = value; }} @Override public SAXParser dispatchto (String qName, Attributes Attributes) {if (docume NT = = null) {return nUll            } if (Qname.equals ("Extendeddata")) {return new Extendeddata.extendeddataparser (document);            }else if (qname.equals ("Placemark")) {return new Placemark.placemarkparser (document);        } return null;        } @Override public void Parserend () {kml.document = document; }    }

public static class Placemarkparser extends SAXParser {private document document;        Private Placemark Placemark;            Public Placemarkparser (document document) {Super (new hashset<string> (1));            Childparserqnames.add ("point");        This.document = document;        } @Override public void Parserstart (Attributes Attributes) {placemark = new placemark ();                 } @Override public void Parserelementend (string qName, String value) {if (Qname.equals ("name")) {            Placemark.name = value;            }else if (qname.equals ("when")) {placemark.when = value; }} @Override public SAXParser dispatchto (String qName, Attributes Attributes) {if (qName.            Equals ("point")) {return new Point.pointparser (Placemark);        } return null; } @Override public void Parserend () {document.Placemark = Placemark; }    }

  

public static class Extendeddataparser extends SAXParser {        private document document;        Private Extendeddata Extendeddata;        Public Extendeddataparser (document document) {            super (new hashset<string> (1));            Childparserqnames.add ("Data");            this.document = document;        }        @Override public        void Parserstart (Attributes Attributes) {            extendeddata = new Extendeddata ();        }        @Override public        void Parserelementend (String qName, String value) {        }        @Override public        SAXParser Dispatchto (String qName, Attributes Attributes) {            if (qname.equals ("Data")) {                return new Data.dataparser ( extendeddata);            }            return null;        }        @Override public        void Parserend () {            document.extendeddatas = extendeddata;        }    }

  

......

Parsing results:

  

Android simplifies XML sax parsing

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.