zoukankan      html  css  js  c++  java
  • :Android网络编程--XML之解析方式:SAX

    任何放置在资源(res)目录下的内容可以通过应用程序的R类访问,这是被Android编译过的,而任何放置在资产(assets)目录下的内容会保持它的原始文件格式,为了读取它们,必须使用AssetManager来以字节流的方式读取文件,所以文件和数据保存在资源中更方便访问。

    2. 凡是在R文件中定义的资源都可以通过 “@Static_inner_classes_name/resourse_name”的方式获取如:“@id/button”, @string/app_name。表达式:“@+id/button”,意思是在不久文件中为一些组件添加id属性。+表表示在R.java的名为id的内部类中添加一条记录。

    XML:是Internet环境中跨平台的依赖于内容的技术,是当前处理结构化文档信息的有力工具。使用一系列简单的标记描述数据。(76)

    SAX: 是一种以事件为驱动的XML API,由它定义的事件流可以指定从解析器传到专门的处理程序代码的XML结构,简单的讲,它是个解析速度快,占用内存少的解析器,这种技术特别适用于Android等移动设备。

    备注:以事件为驱动

    简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 事件驱动的核心自然是事件。从事件角度说,事件驱动程序的基本结构是由一个事件收集器、一个事件发送器和一个事件处理器组成。事件收集器专门负责收集所有事件,包括来自用户的(如鼠标、键盘事件等)、来自硬件的(如时钟事件等)和来自软件的(如操作系统、应用程序本身等)。事件发送器负责将收集器收集到的事件分发到目标对象中。事件处理器做具体的事件响应工作,它往往要到实现阶段才完全确定,因而需要运用虚函数机制(函数名往往取为类似于HandleMsg的一个名字)。对于框架的使用者来说,他们唯一能够看到的是事件处理器。这也是他们所关心的内容。

    DEMO:使用SAX解析XML文档:

    1.创建一个Person类,存放相关的信息:

    package com.example.model;

    public class Person {
    private Integer id;
    private String name;
    private Short age;

    public Person() {
    // TODO Auto-generated constructor stub
    }


    public Person(Integer id, String name, Short age) {
    super();
    this.id = id;
    this.name = name;
    this.age = age;
    }


    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public Short getAge() {
    return age;
    }

    public void setAge(Short age) {
    this.age = age;
    }

    @Override
    public String toString() {
    // TODO Auto-generated method stub
    return "id=" +id +",name="+name+",age=" + age;
    }

    }

    2.创建一个SAXForHandler类,继承自DefaultHandler,DefaultHandler实现了ContentHandler,ContentHandler提供了相应的方法。

    package com.example;

    import java.util.ArrayList;
    import java.util.List;

    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;

    import android.util.Log;

    import com.example.model.Person;

    public class SAXForHandler extends DefaultHandler {
    private static final String TAG = "SAXForHandler";
    private List<Person> persons;
    private String perTag; // record the name of previous tag
    Person person;// current person

    public List<Person> getPersons() {
    return persons;
    }

    /**
    * 在开始解析文档时执行一次
    */
    @Override
    public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    persons = new ArrayList<Person>();
    Log.i(TAG, "****startDocument()****");
    }

    @Override
    public void endDocument() throws SAXException {
    Log.i(TAG, "****endDocument()****");
    }

    /**
    * uri:命名空间
    * localName:标签名称
    * qName:带 命名空间的标签名
    * attributes:存放该标签的所有属性
    */
    @Override
    public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
    if ("person".equals(localName)) {
    for (int i = 0; i < attributes.getLength(); i++) {
    Log.i(TAG, "attributeName:" + attributes.getLocalName(i) + ",attribute_value" +attributes.getValue(i) );
    person = new Person();
    person.setId(Integer.valueOf(attributes.getValue(i)));
    }
    }
    perTag = localName;
    Log.i(TAG, qName + "****startElement()****" );

    }

    @Override
    public void endElement(String uri, String localName, String qName)
    throws SAXException {
    Log.i(TAG, "qName" + "***endElement()***");
    if("person".equals(localName)){
    persons.add(person);
    person =null;
    }
    perTag = null;
    }

    /**
    * ch:当前读取到的TextNode节点
    * start:字节开始的位置,如果要读取全部,那就是从0开始
    * length:当前TextNode的长度
    */
    @Override
    public void characters(char[] ch, int start, int length)
    throws SAXException {
    String data = new String(ch,start,length).trim();
    if(!"".equals(data)){
    Log.i(TAG, "content" + data);
    }
    if("name".equals(perTag)){
    person.setName(data);
    }else if("age".equals(perTag)){
    person.setAge(new Short(data));
    }
    }

    }

    3.创建一个person.xml文件放在src下:

    <?xml version="1.0" encoding="utf-8"?>
    <persons>
    <person id="1">
    <name>wyy</name>
    <age>27</age>
    </person>
    <person id="2">
    <name>cL</name>
    <age>26</age>
    </person>
    </persons>

    4.测试的activity:

    public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
    List<Person> ps = sax_XML();
    for (int i = 0; i <ps.size(); i++) {
    Person p = ps.get(i);
    Log.i("AA", p.getName() +"id="+p.getId()+",age="+p.getId() );
    }
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

    public List<Person> sax_XML() throws Exception{
    //通过类加载器获取路径,再以输入流的方式放入解析器。
    InputStream is = MainActivity.class.getClassLoader().getResourceAsStream("wangyuanyuan.xml");

    SAXForHandler handler = new SAXForHandler();
    SAXParserFactory spf = SAXParserFactory.newInstance();
    SAXParser saxParser = spf.newSAXParser();
    //使用SAXParser
    // saxParser.parse(is, handler);
    //使用xmlReader
    XMLReader xmlReader = saxParser.getXMLReader();
    xmlReader.setContentHandler(handler);
    xmlReader.parse(new InputSource(is));
    List<Person> list = handler.getPersons();
    is.close();
    return list;
    }

    }

    两种方法使用SAXParser 和xmlReader都可以解析成功。

    除了使用SAX我们还可以使用DOM、PULL等解析XML文档。其中PULL解析器被集成在了android系统中 。PULL解析器不仅仅可以解析XML还可以修改或者生成新的XML文件


    不过最近在我们的项目中一般都是用json解析,更加简洁方便。

    参考:百度百科、《Android 4.0 网络编程》

  • 相关阅读:
    感悟.学习的方式
    IOS地理信息使用
    IOSTimer的例子留个备注
    IOSSelector的用法
    ios中addtarget的用法
    ios绘图时的坐标处理
    mac下装Ruby
    iOSbase64
    ios跳转
    Misha and Palindrome Degree CodeForces
  • 原文地址:https://www.cnblogs.com/yuan1225/p/4444240.html
Copyright © 2011-2022 走看看