XML解析--SAX

XML结构
<title>       hello      </title>
标签开始     文本         标签结束
事件模型

SAX处理XML数据是采用事件的形式来处理,下面我们来简单的做个介绍:

当我们处理XML数据中遇到一个开始标签后SAX会告诉你“我遇到了一个开始标签,这个标签是XXXX”,等你作出反应后,它会继续往下,这时它遇到了一段文本,SAX告诉你“我遇到了一段文本,是XXXX”,然后继续等你作出反应,接着下去就遇到了结束标签,SAX仍然会告诉你“我到了一个结束标签是XXX”。SAX就是以这样的方式将整个XML数据全部处理完。

为何使用SAX解析XML
  • 节约内存
  • 效率高
    SAX解析XML文件采用的是事件驱动,它不需要解析整个文档,而是在解析文档的过程中,判断读到的字符是否符合XML语法的某部分,符合的话就会触发事件(回调方法)。
相关类或方法
类或方法 描述
DefaultHandler类 安卓中内置的用于SAX处理XML的类,但是大多情况下我们都需要继承该类重写部分方法,才能达到处理XML数据的功能。
startDocument 每处理一个XML文档都会响应一次。所以这个方法里可以写需要初始化的代码。
startElement 处理每个节点所触发的方法。
characters 处理一个节点之间的文本时候触发该方法,但是该方法并不会告诉你当前文本的所属标签,而仅仅是告诉你文本内容。
endElement 遇到一个节点的结束标签时,将会出发这个方法,并且会传递结束标签的名称。
endDocument 如果当前的XML文档处理完毕后,将会触发该方法,在此方法内你可以将最终的结果保存并且销毁不需要使用的变量。
执行流程

xml文件

<notic>
   <id>1</id>
   <title>%3cs%3edsds%3c%2fs%3e</title>
   <content>%e5%86%85%e5%ae%b91</content>
   <author>1</author>
</notic>

响应过程:

方法名称 localName(标签名称) ch[](文本名称)
startDocument -- --
startElement notic --
startElement id --
characters -- 1
endElement id --
startElement title --
characters -- %3cs%3edsds%2c%2fs%3e
endElement title --
startElement content --
characters -- %e5%86%85%e5%ae%b91
endElement content --
startElement author --
characters -- 1
endElement author --
endElement notic --
endDocument -- --
localName和qName的区别
<?xml version="1.0" encoding="utf-8"?>  
<websites  
    xmlns:sina="http://www.sina.com"  
    xmlns:baidu="http://www.baidu.com">  
      
    <sina:website sina:blog="blog.sina.com">新浪</sina:website>  
    <baidu:website baidu:blog="hi.baidu.com">百度</baidu:website>  
</websites>  

Namespace(空间名称,命名空间)
引入的原因是为了避免混淆。例如上面的这个XML文档,sina和baidu都有blog属性,定义了两个namespace,就像sax官网说的,用namespace是为了实现更多的扩展功能,作为基本应用,很多时候都用不到它:
sina的namespace: http://www.sina.com
baidu的namespace:http://www.baidu.com

xmlns:sina="http://www.sina.com"  
xmlns:baidu="http://www.baidu.com">  

namespace的值可以任意,但是注意不要重复。一般默认的格式都是以url来作为namespace,比如
xmlns:android="http://schemas.android.com/apk/res/android

Prefix(前缀)
sina:blog中 sina就是前缀。

LocalName(本地名称)
sina:blog 中blog就是localName。

QName(Qualified Name 限定?指定?名称)
sina:blog就是QName,相当于前缀+":"+LocalName。

uri(不是url)
例如sina:blog的uri就是前缀sina的namespace,即"http://www.sina.com"。

例子

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<employees>
    <employee>
        <id>2163</id>
        <name>Kumar</name>
        <department>Development</department>
        <type>Permanent</type>      
        <email>kumar@tot.com</email>
    </employee>
    <employee>
        <id>6752</id>
        <name>Siva</name>
        <department>DB</department>
        <type>Contract</type>       
        <email>siva@tot.com</email>
    </employee>   
    <employee>
        <id>6763</id>
        <name>Timmy</name>
        <department>Testing</department>
        <type>Permanent</type>      
        <email>timmy@tot.com</email>
    </employee>
</employees>

Employee类

public class Employee {
    private String name;
    private int id;
    private String department;
    private String type;
    private String email;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getDepartment() {
        return department;
    }
 
    public void setDepartment(String department) {
        this.department = department;
    }
 
    public String getType() {
        return type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    @Override
    public String toString() {
        return id + ": " + name;
    }
 
    public String getDetails() {
        String result = id + ": " + name + "\n" + department + "-" + type
                + "\n" + email;
        return result;
    }
}

创建一个类继承DefaultHandler类

public class SAXXMLHandler extends DefaultHandler {
 
    private List<Employee> employees;
    private String tempVal;
    private Employee tempEmp;
 
    public SAXXMLHandler() {
        employees = new ArrayList<Employee>();
    }
 
    public List<Employee> getEmployees() {
        return employees;
    }
 
    // Event Handlers
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // reset
        tempVal = "";
        if (qName.equalsIgnoreCase("employee")) {
            // create a new instance of employee
            tempEmp = new Employee();
        }
    }
 
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        tempVal = new String(ch, start, length);
    }
 
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (qName.equalsIgnoreCase("employee")) {
            // add it to the list
            employees.add(tempEmp);
        } else if (qName.equalsIgnoreCase("id")) {
            tempEmp.setId(Integer.parseInt(tempVal));
        } else if (qName.equalsIgnoreCase("name")) {
            tempEmp.setName(tempVal);
        } else if (qName.equalsIgnoreCase("department")) {
            tempEmp.setDepartment(tempVal);
        } else if (qName.equalsIgnoreCase("type")) {
            tempEmp.setType(tempVal);
        } else if (qName.equalsIgnoreCase("email")) {
            tempEmp.setEmail(tempVal);
        }
    }
}

创建XML解析类

public class SAXXMLParser {
    public static List<Employee> parse(InputStream is) {
        List<Employee> employees = null;
        try {
            // create a XMLReader from SAXParser
            XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser()
                    .getXMLReader();
            // create a SAXXMLHandler
            SAXXMLHandler saxHandler = new SAXXMLHandler();
            // store handler in XMLReader
            xmlReader.setContentHandler(saxHandler);
            // the process starts
            xmlReader.parse(new InputSource(is));
            // get the `Employee list`
            employees = saxHandler.getEmployees();
 
        } catch (Exception ex) {
            Log.d("XML", "SAXXMLParser: parse() failed");
        }
 
        // return Employee list
        return employees;
    }
}

使用SAXXMLParser

List<Employee> employees = SAXXMLParser.parse(getAssets().open("employees.xml"));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • SAX方式 使用 DOM解析XML文档时,需要读取整个XML文档,在内存中构架生成代表整个 DOM树的Doucme...
    扒块腹肌阅读 3,726评论 0 4
  • 事件编程模式三要求: 事件源:xml文件事件:解析到开始标签(包含属性),解析到结束标签,解析文本内容监听器:De...
    小小机器人阅读 341评论 0 0
  • 1. XML总结 1.1. XML简介 XML : 可扩展的标记语言。(和HTML非常类似的) 可扩展的。 自定义...
    Ethan_Walker阅读 2,983评论 0 12
  • 包你说口令红包系统源码██咨询:155微/电2105同号2211、钟小姐██包你说系统APP开发,包你说系统模式开...
    马骝猴阅读 386评论 0 0
  • 《永远不变》 1分开后那个雪天 仰天长啸不诡辩 往昔历历在目 不会遗憾 继续追寻那夙愿 不必放手妄情节 是那片祈愿...
    向昕阅读 225评论 0 0