网络-解析网络中的数据

常用格式

在网络上传输数据时最常用得方式有两种:XMLJSON

一、解析XML

解析XML的方式有很多,这里记录比较常用的两种:SAX和Pull解析的方式

待解析的xml文件示例

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id = "11">
        <name>SAX解析</name>
        <age>18</age>
    </person>
    <person id = "13">
        <name>XML1</name>
        <age>43</age>
    </person>
</persons>

使用SAX解析方式

核心工具类

public class SaxHelper extends DefaultHandler {
    private Person person;
    private ArrayList<Person> persons;
    //当前解析的元素标签
    private String tagName = null;

    /**
     * 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
     */
    @Override
    public void startDocument() throws SAXException {
        this.persons = new ArrayList<Person>();
        Log.i("SAX", "读取到文档头,开始解析xml");
    }


    /**
     * 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        if (localName.equals("person")) {
            person = new Person();
            person.setId(Integer.parseInt(attributes.getValue("id")));
            Log.i("SAX", "开始处理person元素~");
        }
        this.tagName = localName;
    }


    /**
     * 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
     */

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //判断当前标签是否有效
        if (this.tagName != null) {
            String data = new String(ch, start, length);
            //读取标签中的内容
            if (this.tagName.equals("name")) {
                this.person.setName(data);
                Log.i("SAX", "处理name元素内容");
            } else if (this.tagName.equals("age")) {
                this.person.setAge(Integer.parseInt(data));
                Log.i("SAX", "处理age元素内容");
            }

        }

    }

    /**
     * 处理元素结束时触发,这里将对象添加到结合中
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (localName.equals("person")) {
            this.persons.add(person);
            person = null;
            Log.i("SAX", "处理person元素结束~");
        }
        this.tagName = null;
    }

    /**
     * 读取到文档结尾时触发,
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        Log.i("SAX", "读取到文档尾,xml解析结束");
    }

    //获取persons集合
    public ArrayList<Person> getPersons() {
        return persons;
    }

}

之后在MainActivity中写一个这样的方法,调用就可以解析了

private ArrayList<Person> readxmlForSAX() throws Exception {
    //获取文件资源建立输入流对象
    InputStream is = getAssets().open("person1.xml");
    //①创建XML解析处理器
    SaxHelper ss = new SaxHelper();
    //②得到SAX解析工厂
    SAXParserFactory factory = SAXParserFactory.newInstance();
    //③创建SAX解析器
    SAXParser parser = factory.newSAXParser();
    //④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
    parser.parse(is, ss);
    is.close();
    return ss.getPersons();
}

Pull解析方式

核心代码

public static ArrayList<Person> getPersons(InputStream xml)throws Exception
{
    //XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance();
    ArrayList<Person> persons = null;
    Person person = null;
    // 创建一个xml解析的工厂  
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
    // 获得xml解析类的引用  
    XmlPullParser parser = factory.newPullParser();  
    parser.setInput(xml, "UTF-8");  
    // 获得事件的类型  
    int eventType = parser.getEventType();  
    while (eventType != XmlPullParser.END_DOCUMENT) {  
        switch (eventType) {  
        case XmlPullParser.START_DOCUMENT:  
            persons = new ArrayList<Person>();  
            break;  
        case XmlPullParser.START_TAG:  
            if ("person".equals(parser.getName())) {  
                person = new Person();  
                // 取出属性值  
                int id = Integer.parseInt(parser.getAttributeValue(0));  
                person.setId(id);  
            } else if ("name".equals(parser.getName())) {  
                String name = parser.nextText();// 获取该节点的内容  
                person.setName(name);  
            } else if ("age".equals(parser.getName())) {  
                int age = Integer.parseInt(parser.nextText());  
                person.setAge(age);  
            }  
            break;  
        case XmlPullParser.END_TAG:  
            if ("person".equals(parser.getName())) {  
                persons.add(person);  
                person = null;  
            }  
            break;  
        }  
        eventType = parser.next();  
    }  
    return persons;  
}  

二、解析JSON

待解析的数据源

[
    { "id":"1","name":"基神","age":"18" },
    { "id":"2","name":"B神","age":"18"  },
    { "id":"3","name":"曹神","age":"18" }
]

Android给我们提供的解析类

  • SONObject: Json对象,可以完成Json字符串与Java对象的相互转换
  • JSONArray: Json数组,可以完成Json字符串与Java集合或对象的相互转换
  • JSONStringer: Json文本构建类,这个类可以帮助快速和便捷的创建JSON text, 每个
    JSONStringer实体只能对应创建一个JSON text
  • JSONTokener:Json解析类
  • JSONException:Json异常

谷歌也提供了一种简单的解析库,GSON

简单的Json解析示例

将解析结果存入对象

public class Person {
    private String id;
    private String name;
    private String age;
    public void setId(String id){
        this.id = id;
    }
    public String getId(){
        return this.id;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setAge(String age){
        this.age = age;
    }
    public String getAge(){
        return this.age;
    }
    @Override
    public String toString() {
        return this.name + "~年方:" + this.age;
    }
}

解析方法

private void parseEasyJson(String json){
    persons = new ArrayList<Person>();
    try{
        JSONArray jsonArray = new JSONArray(json);
        for(int i = 0;i < jsonArray.length();i++){
            JSONObject jsonObject = (JSONObject) jsonArray.get(i);
            Person person = new Person();
            person.setId(i+"");
            person.setName(jsonObject.getString("name"));
            person.setAge(jsonObject.getString("age"));
            persons.add(person);
        }
    }catch (Exception e){e.printStackTrace();}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值