Android basics 09: XML file parsing 01 Sax

Source: Internet
Author: User
Tags call back tagname

This article describes how to parse XML in Android.

Android basics 09: XML file parsing 01 Sax

Android basics 09: XML file parsing 02 dom

Android basics 09: XML file parsing 03 pull

Mainly refer to Android XML file parsing method (1) and Android XML Parsing

It is common for Android phones to process XML data. when data is transmitted on different platforms, we may use XML, Which is platform-independent, it is widely used in data communication. How does one Parse XML file data in Android?

There are usually three methods: Dom, sax, and pull. Pull is the android built-in XML file parser.

To illustrate XML file parsing, I have made an android project. Its content is as follows:

The related files are defined:

River. xml

<? XML version = "1.0" encoding = "UTF-8"?> <Rivers> <river name = "lingqu" length = "605"> <Introduction> lingqu is located in PiXian County, Guangxi Zhuang Autonomous Region. It is one of the oldest canal in the world, it has a reputation as the pearl of ancient water conservancy buildings in the world. Ling Qu, formerly known as Qin shiqu, zhiqu, douhe, and pihe, became open in 214 BC. It was still used in 2217. </Introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> <river name = "" length = "200"> <Introduction> the polyix canal starts south of the Yellow Sea, Haikou, the Sanshan Island in the Bohai Sea is located in Jiannan, Jiaozhou, Pingdu, Gaomi, Changyi, and Laizhou, with a total length of 200 kilometers. The basin covers an area of 5400 square kilometers and runs through the Shandong Peninsula in the north and south directions, communicate with Huang Bo. The Jiaolai canal is diverted from the North-South watershed in the east of Yaojia village in Pingdu. The nanliu River is 30 kilometers long and is imported from the Mawan port to the Jiaozhou Bay. The north flow enters the Laizhou Bay from the Haicang port, which is a North Jiaozhou River with a length of more than 100 kilometers. </Introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> <river name = "" length = "168"> <Introduction> is located in the lower part of the Huai River in Northern Jiangsu Province, gao liangjian on the edge of Hongze Lake in the West flows through six counties (districts), including Hong Ze, Qingpu, Huai 'an, Funing, Sheyang, and Binhai, and a large artificial river course that flows into the sea from the east to the flat port. The total length is 168 km. </Introduction> <imageurl> http://imgsrc.baidu.com/baike/pic/item/389aa8fdb7b8322e08244d3c.jpg </imageurl> </river> </rivers>

Main. xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/tv_type"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello" />    <Button         android:id="@+id/btn_dom"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="dom" />    <Button         android:id="@+id/btn_sax"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="sax" />    <Button         android:id="@+id/btn_pull"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="pull" />    <ListView android:id="@+id/lv_riverlist"                android:layout_width="wrap_content"                 android:layout_height="wrap_content" /> </LinearLayout>

Riveritem. xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  >    <LinearLayout  android:layout_height="wrap_content"  android:layout_width="fill_parent"  android:orientation="horizontal">  <TextView    android:id="@+id/tv_name"         android:layout_width="fill_parent"         android:layout_height="wrap_content"         />  <TextView  android:id="@+id/tv_length"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  />  </LinearLayout>  <TextView  android:id="@+id/tv_introduction"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  /></LinearLayout>

Xmltestactivity. Java

public class XmlTestActivity extends Activity {    /** Called when the activity is first created. */private Button btn_dom;private Button btn_sax;private Button btn_pull;private TextView tv_type;private RiverAdapater riverAdapter;private List<River> rivers;private String fileName="river.xml";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                btn_dom=(Button)findViewById(R.id.btn_dom);        btn_sax=(Button)findViewById(R.id.btn_sax);        btn_pull=(Button)findViewById(R.id.btn_pull);        tv_type=(TextView)findViewById(R.id.tv_type);                ListView listView =(ListView)findViewById(R.id.lv_riverlist);        riverAdapter = new RiverAdapater();        listView.setAdapter(riverAdapter);                btn_dom.setOnClickListener(new OnClickListener(){public void onClick(View v){DomXml domXml=new DomXml();rivers=domXml.getRiversFromXml(fileName, XmlTestActivity.this.getApplicationContext());riverAdapter.setRiverList(rivers);tv_type.setText("dom"+String.valueOf(rivers.size()));}});                btn_sax.setOnClickListener(new OnClickListener(){public void onClick(View v){DomXml domXml=new DomXml();rivers=domXml.getRiversFromXml(fileName, XmlTestActivity.this.getApplicationContext());riverAdapter.setRiverList(rivers);tv_type.setText("sax"+String.valueOf(rivers.size()));}});                btn_pull.setOnClickListener(new OnClickListener(){public void onClick(View v){DomXml domXml=new DomXml();rivers=domXml.getRiversFromXml(fileName, XmlTestActivity.this.getApplicationContext());riverAdapter.setRiverList(rivers);tv_type.setText("pull"+String.valueOf(rivers.size()));}});    }    }

River. Java

public class River implements Serializable {     private static final long serialVersionUID = 1L;     private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getLength() {        return length;    }    public void setLength(int length) {        this.length = length;    }    public String getIntroduction() {        return introduction;    }    public void setIntroduction(String introduction) {        this.introduction = introduction;    }    public String getImageurl() {        return imageurl;    }    public void setImageurl(String imageurl) {        this.imageurl = imageurl;    }    private int length;    private String introduction;    private String imageurl; }

Riveradapater. Java

public class RiverAdapater extends BaseAdapter{private List<River> riverList = Collections.emptyList();        public int getCount() {        return riverList.size();    }    public Object getItem(int position) {        return riverList.get(position);    }    public long getItemId(int position) {        return position;    }        public void setRiverList(List<River> riverList)    {        this.riverList = riverList;        notifyDataSetInvalidated();    }        public class RiverHolder {public TextView rname;public TextView rlength;public TextView rintroduction;}    public View getView(int position, View convertView, ViewGroup parent) {        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.riveritem, null);        RiverHolder wh = new RiverHolder();        wh.rname = (TextView) convertView.findViewById(R.id.tv_name);        wh.rlength = (TextView) convertView.findViewById(R.id.tv_length);        wh.rintroduction = (TextView) convertView.findViewById(R.id.tv_introduction);        River wb = riverList.get(position);        if(wb!=null){            wh.rname.setText(wb.getName());            wh.rlength.setText(String.valueOf(wb.getLength()));            wh.rintroduction.setText(wb.getIntroduction(), TextView.BufferType.SPANNABLE);        }        return convertView;    }}

The first part introduces the method of parsing the sax file:

Sax is: Simple API for XML
Sax is event-driven. Of course, Android's event mechanism is based on callback functions. when parsing XML documents with sax, an event will be called back when the start and end tags of the read documents are obtained, when reading other nodes and content, an event is also called back.
Since events are involved, there is an event source and an event processor. In the sax interface, the event source is xmlreader In the org. xml. Sax package. It parses the XML document through the Parser () method and generates events. The event processor is the contenthander, dtdhander, errorhandler, and entityresolver interfaces in the org. xml. Sax package.
Xmlreader connects to contenthander, dtdhander, errorhandler, and entityresolver through the corresponding event processor registration method setxxxx (). For details, see the following table:

However, we do not need to inherit these four interfaces. the SDK provides the defaulthandler class for processing. Some Major Event Callback methods of the defaulthandler class are as follows:

From the above, we need xmlreader and defaulthandler to parse XML.
The solution is as follows:
1: Create a saxparserfactory object
2: According to the saxparserfactory. newsaxparser () method, a saxparser parser is returned.
3: Get the event source object xmlreader according to the saxparser parser
4: instantiate a defaulthandler object
5: connect the event source object xmlreader to the event processing class defaulthandler.
6: Call the parse method of xmlreader to obtain XML data from the input source.
7: return the data set we need through defaulthandler.
The Code is as follows:

Public class saxxml {public list <river> parse (string xmlpath, context) {list <river> rivers = NULL; saxparserfactory factory = saxparserfactory. newinstance (); try {saxparser parser = factory. newsaxparser (); // obtain the event source xmlreader = parser. getxmlreader (); // set the processor riverhandler handler = new riverhandler (); xmlreader. setcontenthandler (handler); // parse the XML document // xmlreader. parse (New inputsource (new URL (XML Path ). openstream (); xmlreader. parse (New inputsource (context. getassets (). open (xmlpath); rivers = handler. getrivers ();} catch (parserconfigurationexception e) {// todo auto-generated Catch Block E. printstacktrace ();} catch (saxexception e) {// todo auto-generated Catch Block E. printstacktrace ();} catch (ioexception e) {e. printstacktrace ();} return rivers;} public class riverhandler extends Defaulthandler {private Boolean isriver; private Boolean xintroduction; private Boolean ximageurl; private river; private list <river> rivers = NULL; public list <river> getrivers () {return rivers ;} /** receive the notification of the beginning of the document. * // @ Override public void startdocument () throws saxexception {rivers = new arraylist <river> ();} /** navigate to start tag trigger **/Public void startelement (string Uri, string localname, string QNAME, attributes) {string tagname = localname. length ()! = 0? Localname: QNAME; tagname = tagname. tolowercase (). trim (); // if the river tag is read, the river if (tagname. equals (Contant. river) {isriver = true; river = New River ();/** navigate to the river Start Node **/river. setname (attributes. getvalue (Contant. name); River. setlength (integer. parseint (attributes. getvalue (Contant. length);} // then read other nodes if (isriver) {If (tagname. equals (Contant. introduction) {xintroduction = true;} else if (tagname. equ ALS (Contant. imageurl) {ximageurl = true ;}}/ ** navigate to the end label to trigger **/Public void endelement (string Uri, string localname, string QNAME) {string tagname = localname. length ()! = 0? Localname: QNAME; tagname = tagname. tolowercase (). trim (); // if the river tag is read, add If (tagname. equals (Contant. river) {isriver = true; rivers. add (river);} // then read other node if (isriver) {If (tagname. equals (Contant. introduction) {xintroduction = false;} else if (tagname. equals (Contant. imageurl) {ximageurl = false ;}}// the callback public void characters (char [] CH, int start, int length) when the node content is read) {// set the property value if (Xin Troduction) {// solve the null problem river. setintroduction (river. getintroduction () = NULL? "": River. getintroduction () + new string (CH, start, length);} else if (ximageurl) {// solve the problem of null River. setimageurl (river. getimageurl () = NULL? "": River. getimageurl () + new string (CH, start, length ));}}}}

The focus is on processing each element node, attribute, text content, and document content in the defaulthandler object.
As mentioned above, defaulthandler is based on the event processing model. The basic processing method is to call back the startdocument method when the SAX Parser navigating to the start tag of the document, and to call back the enddocument method when the end tag of the document. The SAX Parser calls back the startelement method when the element starts the tag, calls back the characters method when it is navigating to its text content, and calls back the endelement method when the Tag ends.
Based on the above explanation, we can draw the following logic for processing XML documents:
1: When navigation to the document start label, in the callback function startdocument, You can do not deal with, of course you can verify the UTF-8 and so on.
2: When you navigate to rivers to start the tag, you can instantiate a set in the callback method startelement to store the list, but we don't need it here because it has been instantiated in the constructor.
3: When you navigate to the river start label, it indicates that the river object needs to be instantiated. Of course, the river label also contains the name and length attributes. Therefore, the attribute value, attributes, must be taken out after the river is instantiated. getvalue (name) is used to assign a Boolean to the river object and add a Boolean to the river label to indicate that the river element is located.
4: Of course, there are also sub-tags (nodes) in the river tag, but the SAX Parser does not know what label to navigate to. It only knows the start and the end. So how can we make it recognize our labels? Of course, you need to determine, so you can use the string localname parameter in the callback method startelement to compare our tag string with this parameter. We must also let sax know. Now we are navigating to a tag, so add a true attribute to let the SAX Parser know. Therefore
5: it will also navigate to the text label (that is, the content in </img>), the callback method characters, in this method, we usually extract the content in </img> and save it.
6: Of course, it will definitely navigate to the end tag </river> or </rivers>. If it is a </river> tag, remember to add the river object to the list. If it is a sub-tag in the river </introduction>, set the Boolean tag marked previously to false.

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.