Android中数据解析的几种方式

原文在:http://blog.csdn.net/baidu_32877851/article/details/51570163

这里有一份XML文件,接下来我们用不同的解析方式来解析这份文件

<?xml version="1.0" encoding="UTF-8"?>
<Movies>
    <Movie id="1">
        <name>愤怒的小鸟</name>
        <type>Animation</type>
        <year>2016</year>
    </Movie>
    <Movie id="2">
        <name>叶问3</name>
        <type>Action</type>
        <language>English</language>
    </Movie>
</Movies>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

1.DOM解析

//1.创建一个DocumentBuilderFactory对象
        DocumentBuilderFactory dBuilderFactory=DocumentBuilderFactory.newInstance();
        try {
            //2.创建一个DocumentBuilder对象
            DocumentBuilder dBuilder=dBuilderFactory.newDocumentBuilder();
            //3.获取Document对象
            Document document=dBuilder.parse("Movie.xml");
            System.out.println("解析开始:--------------------------");
            //获取Movie元素结点集合
            NodeList movies=document.getElementsByTagName("Movie");
            System.out.println("共有"+movies.getLength()+"部电影");
            //遍历Movie元素结点集合
            for(int i=0;i<movies.getLength();i++){
                System.out.println("=====================");
                System.out.println("正在解析"+(i+1)+"部电影!");
                Node movie=movies.item(i);
                //获取元素结点的属性集合
                NamedNodeMap attrs=movie.getAttributes();
                for(int j=0;j<attrs.getLength();j++){
                    Node attr=attrs.item(j);
                    System.out.print("属性名为:"+attr.getNodeName()+"        ");
                    System.out.println("属性值为:"+attr.getNodeValue());
                }
                //获取movie元素子节点集合
                NodeList childNodes=movie.getChildNodes();
                for(int k=0;k<childNodes.getLength();k++){
                    Node child=childNodes.item(k);
                    if (child.getNodeType()==Document.ELEMENT_NODE) {
                        System.out.println("节点名:"+child.getNodeName()+"       ");
                        //System.out.println("节点值:"+child.getNodeValue());
                        System.out.println("节点值:"+child.getFirstChild().getNodeValue());
                    }
                }
                System.out.println("第"+(i+1)+"部电影解析结束");
            }
            System.out.println("解析结束--------------------------------");
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2.SAX解析

//1.创建SAXFactory对象
        SAXParserFactory sParserFactory=SAXParserFactory .newInstance();
        //2.拿到一个SAXParser解析对象
        try {
            SAXParser saxParser=sParserFactory.newSAXParser();
            saxParser.parse("Movie.xml",new MyHandler() );
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

接下来需要写一个类去继承DefaultHandler,然后一般要重写里面的五个方法: 
1)startDocument(),该方法一执行表示解析开始,可以在里面去初始化对象集合

@Override
    public void startDocument() throws SAXException {
        System.out.println("开始解析----------------------------");
        movieList=new ArrayList<>();
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

2)startEnement(),该方法一执行表示解析到了开始元素,亦即xml文件里面的Movie标签

@Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //
        if ("Movie".equals(qName)) {
            movie=new Movie();
            count++;
            System.out.println("正在解析第"+count+"部电影!");
            for (int i = 0; i < attributes.getLength(); i++) {
                //拿到属性名和属性值
                System.out.print("属性名:"+attributes.getQName(i)+"       ");
                System.out.println("属性值:"+attributes.getValue(i));
                if (attributes.getQName(i).equals("id")) {
                    movie.setMovieId(attributes.getValue(i));
                }
            }
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3)characters(),在该方法里面去读取元素的值

@Override
    public void characters(char[] ch, int start, int length) throws SAXException {

        value=new String(ch,start,length);
        if (!value.trim().equals("")) {
            System.out.println("节点值:"+value);
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4)endElement(),表示解析到了一个元素的结束标签,在该方法里面可以去 构造对象,最后并且添加到集合里去

@Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equals("year")) {
            movie.setMovieYear(value);
        }
        if (qName.equals("type")) {
            movie.setMovieType(value);
        }
        if (qName.equals("language")) {
            movie.setMovieLanguage(value);
        }
        if (qName.equals("name")) {
            movie.setMovieName(value);
        }
        //解析完一个元素时回调
        if ("Movie".equals(qName)) {
            movieList.add(movie);
            movie=null;
            System.out.println("第"+count+"部电影解析结束!");
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5)endDocument(),当执行到该方法也就表示文件已经解析完毕了

@Override
    public void endDocument() throws SAXException {
        System.out.println("解析结束----------------------------");
        System.out.println("解析结果集如下:");
        for(int i=0;i<movieList.size();i++){
            System.out.println(movieList.get(i).toString());
            System.out.println("----------------------------------");
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.PULL解析 
pull解析与其它方式不同的是,它需要将xml文件存放在资源文件res下面的xml文件夹下,解析的过程如下: 
1)首先拿到一个Pull资源解析器,有时如果通过网络上下载xml文件的话,则需要去构造一个Pull解析器,再将流设置给pull解析器, 
接下来就是一样的,一个标签一个标签的去解析,

//拿到一个XMLResourceParser
        //XmlPullParser parser=Xml.newPullParser();
        //parser.setInput(in);
        XmlResourceParser xmlResourceParser=getResources().getXml(R.xml.movie);

        //拿到第一个事件类型,也就是最外层的标签
        try {
            int type=xmlResourceParser.getEventType();
            while(type!=XmlResourceParser.END_DOCUMENT){
                if (type==XmlResourceParser.START_DOCUMENT) {
                    System.out.println("开始解析");
                    movieList=new ArrayList<>();
                }
                if (type==XmlResourceParser.START_TAG) {
                    if ("Movie".equals(xmlResourceParser.getName())) {
                        movie=new Movie();
                        String id=xmlResourceParser.getAttributeValue(null, "id");
                        System.out.println("id:"+id);
                        movie.setMovieId(id);
                    }
                    if ("name".equals(xmlResourceParser.getName())) {
                        //System.out.println("name:"+xmlResourceParser.nextText()+"===========");
                        movie.setMovieName(xmlResourceParser.nextText());
                    }else if ("type".equals(xmlResourceParser.getName())) {
                        movie.setMovieType(xmlResourceParser.nextText());
                    }else if ("year".equals(xmlResourceParser.getName())) {
                        movie.setMovieYear(xmlResourceParser.nextText());
                    }else if ("language".equals(xmlResourceParser.getName())) {
                        movie.setMovieLanguage(xmlResourceParser.nextText());
                    }
                }
                if (type==XmlResourceParser.END_TAG) {
                    if ("Movie".equals(xmlResourceParser.getName())) {
                        movieList.add(movie);
                        movie=null;
                    }
                }
                type=xmlResourceParser.next();
            }
            System.out.println("解析结束");
            StringBuffer sBuffer=new StringBuffer();
            for (int i = 0; i < movieList.size(); i++) {

                sBuffer.append(movieList.get(i).toString())
                .append("\n");
            }
            show_tv.setText(sBuffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

4.Json解析 
Json解析的话需要先给出一份JSon数据,就拿下面的数据来解析吧!

private static final String JSONDATA="{name:张三,"
            + "age:26,"
            + "phone:[131,132],"
            + "score:{"
            + "语文:100,"
            + "数学:90,"
            + "理综:{化学:80,物理:70,生物:80}}}";
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Json解析的过程无疑就是碰到大括号,就new一个Object出来,中括号就new一个Array出来,再用一个for循环去读取数据:

StringBuffer stringBuffer=new StringBuffer();
        try {
            //JSONObject jsonObject=new JSONObject(JSONDATA);
            JSONTokener jsonTokener=new JSONTokener(JSONDATA);
            JSONObject jsonObject=(JSONObject) jsonTokener.nextValue();
            stringBuffer.append("name:"+jsonObject.getString("name")+"\n");
            stringBuffer.append("aeg:"+jsonObject.getString("age")+"\n");
            JSONArray phoneArray=jsonObject.getJSONArray("phone");
            stringBuffer.append("phone:"+phoneArray.getString(0)
                                            +"    "+phoneArray.getString(1)+"\n");
            JSONObject scoreJsonObject=jsonObject.getJSONObject("score");
            stringBuffer.append("语文:"+scoreJsonObject.getString("语文")+"\n")
            .append("数学:"+scoreJsonObject.getString("数学"));
            JSONObject lizongObject=scoreJsonObject.getJSONObject("理综");
            stringBuffer.append("化学:"+lizongObject.getString("化学")+"\n")
            .append("物理:"+lizongObject.getString("物理")+"\n")
            .append("生物:"+lizongObject.getString("生物"));
            show_tv.setText(stringBuffer.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.GSON解析 
GSON解析相对来说简单一些,但也有一定的局限性,比如说,数据类的属性字段和key值必须是一一对应的

//拿GSON去解析数据时,数据类的属性值跟key值必须是对应的
        Gson gson=new Gson();
        Student student=gson.fromJson(JSONDATA, Student.class);
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

数据类的属性:

public String name;
public String age;
public ArrayList<String> phone=new ArrayList<>();
public ArrayList<Score> score=new ArrayList<>();
public class Score{
    public String id;
    public String fenshu;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值