XML解析--SAX

XML结构
       hello      
标签开始     文本         标签结束
事件模型

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文件


   1
   %3cs%3edsds%3c%2fs%3e
   %e5%86%85%e5%ae%b91
   1

响应过程:

方法名称 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的区别
  
  
      
    新浪  
    百度  
  

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文件



    
        2163
        Kumar
        Development
        Permanent      
        [email protected]
    
    
        6752
        Siva
        DB
        Contract       
        [email protected]
       
    
        6763
        Timmy
        Testing
        Permanent      
        [email protected]
    

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 employees;
    private String tempVal;
    private Employee tempEmp;
 
    public SAXXMLHandler() {
        employees = new ArrayList();
    }
 
    public List 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 parse(InputStream is) {
        List 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 employees = SAXXMLParser.parse(getAssets().open("employees.xml"));

你可能感兴趣的:(XML解析--SAX)