Android开发之XML文件解析的使用

时间:2021-12-22 07:13:01

  前言 

  本文主要介绍在android中怎样来解析xml文件。主要采用的是sax机制,sax全称为simple api for xml,它既是一种接口,也是一个软件包。作为接口,sax是事件驱动型xml解析的一个标准接口。xml文件解析一般有2种方法,dom和sax。其中dom需要先将xml文档全部读入到电脑内存中,当文档内容太大时,该方法并不适用。sax就比较好的解决了该问题,它是逐行解析的,可以随时中断。但是sax的操作比较复杂。因此,这2种方法各有优缺点,看具体应用情况。在前面的文章qt学习之路_12(简易数据管理系统)中使用的是qt中的dom方法。

  实验说明

  大多数sax实现都会产生类似下面的事件:

  在文档的开始和结束处触发文档处理事件;在文档内每一xml元素结束解析的前后触发元素事件;任何元数据通常豆油单独的事件交付;在处理文档的dtd或者schema时产生dtd 或者schema事件;产生错误事件用来通知主机应用程序解析错误。

  sax模型示意图如下所示:

  Android开发之XML文件解析的使用

  如果要用sax来解析xml文档,则需要一个类来继承android系统提供的contenthandler类。但是如果继承contenthandler这个类, 即使你不使用这个类提供的所有方法,你也必须实现其内部的所有方法(一般情况下没有使用的方法可以直接用空方法代替),但是这样开发起来不是很方便。因此我们可以改为继承defaulthandler这个类,这样的话我们只需要实现程序中所需要的方法即可,其它的方法这个类内部其实已经用空方法代替了。

contenthandler接口的方法有以下几种:

void startdocument();//文档解析开始时执行

void enddocument();//文档解析结束时执行

void startelement(string uri, string localname, string qname, attributes atts);//标签开始解析时执行

void endelement(string uri, string localname, string qname, attributes atts);//标签解析结束时执行

void characters(char[] ch, int start, int length );//解析标签属性时执行

  android中使用sax来解析xml文件,需先建立一个sax工厂,即saxparserfactory对象,还需建立一个xmlreader对象,该类绑定contenthandler子类,且与xml源文件结合在一起。即其处理过程为创建事件处理程序,创建sax解析器,键事件处理程序分配给解析器,对文档进行解析,将每个事件发送给处理程序。 

  判断string类型的值是否相等采用的是string类的equal方法。 

  本实验是解析一段xml代码,然后在上面每个解析函数中打印一些内容。主要是学会怎么使用sax模型来来创建解析器,怎样使用contenthandler子类的函数来进行解析。

  实验主要部分代码:

mainactivity.java:

 

复制代码 代码如下:

package com.example.xml;

 

import java.io.stringreader;

import javax.xml.parsers.saxparserfactory;

import org.xml.sax.inputsource;
import org.xml.sax.xmlreader;

import android.app.activity;
import android.os.bundle;
import android.view.menu;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.textview;

public class mainactivity extends activity {

    private button start  = null;
    private textview display = null;
    @override
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        setcontentview(r.layout.activity_main);
        start = (button)findviewbyid(r.id.start);
        start.setonclicklistener(new startonclicklistener());
    }

    public class startonclicklistener implements onclicklistener{

        public void onclick(view v) {
            // todo auto-generated method stub
            //注意2点,第1:字符串中如果要换行写,则应该用引号和加号来相加得到,不能直接换行写
            //第2点:如果字符串中有字符,则用括号里面的符合(\")代替引号。
            //我这里用的xml文件直接为该程序layout的布局xml文件
//            string result_str =
//            "<relativelayout " +
//              "  xmlns:tools=\"http://schemas.android.com/tools\" " +
//              "  android:layout_width=\"match_parent\" " +
//              "  android:layout_height=\"match_parent\" > " +
//           
//             "   <button  " +
//               "     android:id=\"@+id/start\"    " +
//                 "   android:layout_width=\"fill_parent\"    " +
//                  "  android:layout_height=\"wrap_content\"    " +
//                 "   android:layout_alignparentbottom=\"true\"    " +
//                  "  android:text=\"start xml parse\"    "    +
//                "    /> " +
//              "  <textview " +
//                "    android:id=\"@+id/display\" " +
//               "     android:layout_width=\"fill_parent\"    " +
//                "    android:layout_height=\"fill_parent\"    " +
//                "    android:gravity=\"center\"    " +
//                "     android:layout_alignparentleft=\"true\"    "    +
//                "     android:layout_above=\"@+id/start\"    "    +
//                "     android:text=\"the xml parse example!!\"    " +
//                "    />    " +
//        "    </relativelayout>";

            string result_str =        
             "   <button  " +
               "     id=\"@+id/start\"    " +
                 "   layoutwidth=\"fillparent\"    " +
                  "  layoutheight=\"wrapcontent\"    " +
                 "   layoutalignparentbottom=\"true\"    " +
                  "  text=\"start xml parse\"    "    +
                "    </button> " ;

           
            system.out.println(result_str);
            try{
                //创建sax工厂
                saxparserfactory factory = saxparserfactory.newinstance();
                xmlreader reader = factory.newsaxparser().getxmlreader();
                reader.setcontenthandler(new mycontenthandler());
                reader.parse(new inputsource(new stringreader(result_str)));
            }
            catch(exception e) {
                e.printstacktrace();
            }

        }

    }
    @override
    public boolean oncreateoptionsmenu(menu menu) {
        getmenuinflater().inflate(r.menu.activity_main, menu);
        return true;
    }
}

mycontenthandler.java:

复制代码 代码如下:


package com.example.xml;

 

import org.xml.sax.attributes;
import org.xml.sax.saxexception;
import org.xml.sax.helpers.defaulthandler;

public class mycontenthandler extends defaulthandler {

    string tagname, sid, swidth, sheight, text, salign;

    //当解析到标签的属性栏时调用该方法
    @override
    public void characters(char[] ch, int start, int length)
            throws saxexception {
        // todo auto-generated method stub
        if(tagname.equals("id"))
            sid = new string(ch, start, length);
        else if(tagname.equals("layoutwidth"))
            swidth = new string(ch, start, length);
        else if(tagname.equals("layoutheight"))
            sheight = new string(ch, start, length);
        else if(tagname.equals("layoutalignparentbottom"))
            salign = new string(ch, start, length);
        else if(tagname.equals("text"))
            text = new string(ch, start, length);
        super.characters(ch, start, length);
    }

    //解析文档结束调用
    @override
    public void enddocument() throws saxexception {
        // todo auto-generated method stub
        system.out.println("........end.......");
        super.enddocument();
    }

    //解析标签结束时调用
    @override
    public void endelement(string uri, string localname, string qname)
            throws saxexception {
        // todo auto-generated method stub
        if(tagname.equals("button")) {
            this.printout();
        }
        super.endelement(uri, localname, qname);
    }

    //解析文档开始时调用
    @override
    public void startdocument() throws saxexception {
        // todo auto-generated method stub
        system.out.println("........begin.......");
        super.startdocument();
    }

    //标签开始时执行
    @override
    public void startelement(string uri, string localname, string qname,
            attributes attributes) throws saxexception {
        // todo auto-generated method stub
        tagname = localname;
        if(tagname.equals("button")) {
            for(int i = 0; i < attributes.getlength(); i++) {       
                //得到第i个属性的名字和值
                system.out.println(attributes.getlocalname(i) + "=" + attributes.getvalue(i));
            }

        }
        super.startelement(uri, localname, qname, attributes);
    }

    //输出标签属性解析结果
    private void printout() {
        system.out.print("id: ");
        system.out.println(sid);
        system.out.print("layout_width: ");
        system.out.println(swidth);
        system.out.print("layout_height: ");
        system.out.println(sheight);
        system.out.print("layout_alignparentbottom: ");
        system.out.println(salign);
        system.out.print("text: ");
        system.out.println(text);
    }

}