XML解析 与 JSON 解析

1.SAX
  SAX(simple API for XML),一种基于事件驱动模型的XML解析标准接口。
  工作原理:
  SAX简单地说就是对XML文档进行顺序扫描,当扫描到文档的开始与结束 , 元素(element)的开始与结束时,就会触发相应的事件处理 函数,由事件处理函数做相应的动作,处理完后继续扫描,直到文档结束,则解析完毕。

 实现步骤:
    (1)SAXParserFactory fa = SAXParserFactory .newInstance();  //获得SAX解析工厂对象
    (2)XMLReader reader = fa. newSAXParser().getXMLReader(); //通过SAX解析工厂对象得到一个XMLReader
    (3)reader.setContentHandler(new MySAXContentHandler());  //注册ContentHandler内容解析监听对象
    (4)reader.parse (new InputSource(new StringReader(xmlStr))); //开始解析XML文件
 
  步骤说明:
    对于每个XMLReader 可以注册四种监听接口 ,分别为 ContentHandler,DTDHandler,ErrorHandler以及EntityResolver,其中    ContentHandler 为最主要的,也是最经常使用的接口。

    调用parse方法解析XML文件,需要的是一个InputSource对象,而InputSource对象又需要一个Reader字符流对象,所以可以通过
    new InputSource(new StringReader(xmlStr)) 的方式,来生成一个InputSource对象,供XMLReader对象解析所用。
    这里的StringReader是以提供的String 数据所创建一个字符流。

  ContentHandler:
   在XMLReader解析XML文件的时候,会触发所注册的ContentHandler内的方法,关键方法如下:
   public void startDocument()  //开始解析文档
   public void endDocument()  //结束解析文档
   public void startElement()  //开始解析元素
   public void endElement()  //结束解析元素
   public void characters()   //读取元素的内容

   下面以一个实例来说明:

   首先是需要解析的XML文件: students.xml
 <?xml version="1.0" encoding="utf-8"?>
<studentlist>
<student attr1="ar1" attr2="ar2">
<id>1</id>
<name>jack</name>
<age>18</age>
</student>

<student attr1="ar1" attr2="ar2">
<id>2</id>
<name>tom</name>
<age>20</age>
</student>
</studentlist>

把这个文件放在Android工程目录下的res/raw文件夹内,然后调用getResource().openRawResource(R.id.students)得到一个输入流,将其读取到程序中来。代码如下:
     /**
     * 以字符流的形式从res/raw文件夹中读取students.xml文件
     */
    public void getXMLFile2String()
    {
         StringBuffer buffer = new StringBuffer();
        BufferedReader bufferReader = null;
        try {
             String line =null;
              bufferReader = new BufferedReader(new InputStreamReader( getResources().openRawResource(R.raw.students)));
             
             while((line=bufferReader.readLine())!=null)
             {
                 buffer.append(line);
             }
             xmlStr=buffer.toString();//读取完毕后赋值给
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(bufferReader!=null)
            {
                try {
                    bufferReader.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

再定义一个对应的Student持久化类,代码如下:
 public class Student {
    private String id;
    private String name;
    private String age;
   
    public Student(){}

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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


实现自己的ContentHandler:
 可以通过实现ContentHandler接口来定义自己的ContentHandler,不过这样做就会有很多用不上的方法被空实现出来,所以这里采用继承 org.xml.sax.helpers.DefaultHandler类,把需要用到的方法实现出来即可,代码如下:
 public class MySAXContentHandler extends DefaultHandler{
    private String curentTag;  //当前读取到的标签
 
    private List<Student> stus = new ArrayList<Student>();
    private Student stu;

    @Override
    public void startDocument() throws SAXException {
        System.out.println("start----");
    }

    @Override
    public void endDocument() throws SAXException {
        System.out.println("end-----");
        printAll();
    }

    /**
     *  url 标签的命名空间
     *  localName 不带前缀的标签名
     *  qName 带前缀的标签名
     *  attributes 标签的属性
     */

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
         curentTag=localName;
        if(localName.equals("student")){
            stu = new Student();
            for(int i=0;i<attributes.getLength();i++) //打印所有的属性
            {
                System.out.println(attributes.getLocalName(i)+" is :"+attributes.getValue(i));
            }
        }
    }
   
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if(localName.equals("student")){
            stus.add(stu);
        }
    }
      /**
     *  ch 标签的内容所对应的字符数组
     *  start 开始位置
     *  length 长度
     */

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if(curentTag.equals("name")){
            stu.setName( new String(ch,start,length));
        }else if(curentTag.equals("id")){
            stu.setId(new String(ch,start,length));
        }else if(curentTag.equals("age")){
            stu.setAge(new String(ch,start,length));
        }
    }
   
     //打印所有的学生信息
    public void printAll()
    {
        for(Student s:stus)
        {
            System.out.println(s.getId());
            System.out.println(s.getName());
            System.out.println(s.getAge());
        }
    }
}

这里需要说明一下,使用自定义的ContentHandler解析XML文件的时候,需要提供一个String  curentTag 对象来记录当前正在解析的是哪一个标签,通过在startElement方法中实时的更新,而在characters方法中通过对 curentTag 的判断来实行不同的操作。
 
总结:使用SAX来解析XML文件,实际上是一个边读边解析的过程,当文件读取完毕后,也就解析完毕。而其中ContentHandler是最主要的解析监听接口,它以标签为基本单位,在解析时候触发相应方法,在方法中会传入相应的参数,以对不同的标签进行不同的操作。





2.DOM
  DOM(Document Object Model),是一种基于文档对象模型的解析XML标准接口。
  工作原理:
  DOM解析XML文件时,会将XML文件的所有内容读取到内存中,然后允许你使用DOM API 操作XML 树。也就是说,DOM 会把XML以树的形式读取到内存中,然后在通过相应的API 来操作这个XML树,从而达到解析XML文件的目的。
  一般不建议在手机上采用DOM来解析XML,因为这样会占用比较多的内存

 ps:DOM是由w3c定义的一个解析XML的标准,一些第三方类库在此基础上扩展并优化了解析的过程,其中dom4j和jdom都是比较优秀的第三方类库。





3.JSON(JavaScript Object Natation),JSON数据是一系列键值对的集合,在网络传输中被广泛应用。
 json的结构:
 {"name":"Jack", "address": { "city":"Shanghai", "street":"Pufa Road" }}
 说明:一对{  }代表一个json对象。
        “key”:“value”, 代表一个键值对 。
        而一个key又可以指向一个json对象。

JSON数组:
多个json对象形成的数组,例如:
[ {
"name":"Jack","age":1" } , { "name":"tom","age":18 } ]


JSON的解析:
      Android3.0提供了JsonReader这样一个类,其本质其实也是Gson,也就是Google一个开源的用于解析JSON的类库。所以为了使用这个类库来解析JSON,必须添加gson-1.6.jar包。(可到Google网站下载)
    
     JSON的解析又可以分两个方向:
      一种是类似SAX的事件监听模式,如下;
   
         private String jsonArray = "[ {\"name\":\"Jack\",\"age\":12} , {\"name\":\"tom\",\"age\":18} ]";

        public static void parseJSON(String jsonArray)
    {
        try {
            JsonReader reader = new JsonReader(new StringReader(jsonArray));
            reader.beginArray();
           
            while(reader.hasNext())
            {
                reader.beginObject();
                while(reader.hasNext())
                {
                    String keyName = reader.nextName();
                    if(keyName.equals("name")){
                        System.out.println("name is "+reader.nextString());
                    }else if(keyName.equals("age"))
                    {
                        System.out.println("age is "+reader.nextInt());
                    }
                }
                reader.endObject();//
            }
            reader.endArray();//
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   另外一种是可以直接即将JSON转换为持久化类,如下:

   private String jsonArray = "[ {\"name\":\"Jack\",\"age\":12} , {\"name\":\"tom\",\"age\":18} ]";
        
   public static void parseJSONArray2ObjecList(String jsonArray)
    {
        Type listType = new TypeToken<LinkedList<User>>(){}.getType();//反射得到一个Type对象
        LinkedList<User> list = new Gson().fromJson(jsonArray, listType);
       
        Iterator<User> iterator = list.iterator();
       
        while(iterator.hasNext())
        {
            User user = (User)iterator.next();
            System.out.println("name is " + user.getName());
            System.out.println("age is" + user.getAge());
        }
    }

对应的持久化类:
public class User {

    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

  新建一个JSON:
public static void newJSON()
    {
       
        List<User> users = new ArrayList<User>();

        User user1 = new User();
        user1.setAge(25);
        user1.setName("tonmy");
        users.add(user1);
       
        User user2 = new User();
        user2.setAge(45);
        user2.setName("peter");
        users.add(user2);
       
       
        Gson gson = new Gson();
        String jsonStr = gson.toJson(users);
       
        System.out.println(jsonStr);
    }

     打印出来的字符串为:[ { "name":"tonmy" , "age":25 } , { "name":"peter","age":45 } ]

总结:JSON其实就是满足特定规则的一种数据形式,它提供了一个方便快捷的数据交换途径,在与JavaScript的交互中有良好的表现,因为JavaScript可直接识别出JSON而不需要在做其他的出来,这点相对于XML还是比较方便的。但对一些拥有复杂结构的数据,使用JSON就不是那么适合。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值