Xml解析网络数据

现在都应该使用最新的框架进行解析网络数据,很少有人会使用xml解析,因为xml解析不仅麻烦,又浪费时间,但是以前比较老的项目大多都是使用xml解析的,所以说xml解析我们也需要学会,

XML解析:
startDocument 从文件开始:此方法中一般做一些准备工作,例如创建集合对象存储解析结果,与endDocument对应

startElement 从元素开始:此方法中进入xml数据开始解析,一般处理一些localName,将形参Localname 赋值给实参使用, localName类似于json数据中的key

characters: 开始解析数据: 此方法类似于json数据解析中 以key取对应的value,方法中有三个参数,分别是char数组,代码整个数据的字符数组, int类型的start代码某localName(key)值对应的内容(value)的起始位置,int类型的length代表localName(key)对应内容(value)的长度,将这三个参数传入String的构造方法,创建一个String。该String就是localName(key)对应的内容(value)。要时刻谨记:血淋淋的教训啊:“xxx”.equals(tag)

endElement 和startElement对应,在此处将缓存的tag清空,将bean加入集合,将缓存的bean清空去处理下一次数据

endDocument 和startDocument对应,在此方法中处理解析完成的数据

在MainActivity中使用,

public class MainActivity extends AppCompatActivity {

    private String url = "http://api.ithome.com/xml/newslist/news.xml";
    private Handler handler;
    private InputStream is;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         * 1.开启线程,请求网络数据
         * 2.在线程中,获取到的输入流传送到,解析帮助类中,
         * 3.handler把解析解结果发送回来
         */
        handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {

                if (msg.what == 102) {
                    List<XmlBean> datas = (List<XmlBean>) msg.obj;
                    for (int i = 0; i < datas.size(); i++) {
                        Log.d("MainActivity", "datas.get(i):" + datas.get(i));
                    }
                }
                return false;//true与false是否处理
            }
        });
        new DataThread(handler, url).start();
    }

}

根据需要解析的网址来创建数据类,这里就以这三个属性来举例说明,

public class XmlBean {

    private String title;
    private String image;
    private String description;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

需要一个线程来获取网络数据流,

public class DataThread extends Thread {
    private Handler handler;
    private String url;
    //创建输入流
    InputStream is = null;

    private HttpURLConnection connection;

    public DataThread(Handler handler, String url) {
        this.handler = handler;
        this.url = url;
    }

    @Override
    public void run() {
        super.run();
        try {
            //1.创建url对象,
            URL u = new URL(url);
            //2.利用url对象打开网络连接
            connection = (HttpURLConnection) u.openConnection();

            if (connection.getResponseCode() == 200) {
                is = connection.getInputStream();
                //输入流来源网络,你把输入流发回主线程
                //主线程中处理这个流,其实就是在UI线程中进行网络的工作
                SAXParserFactory spf = SAXParserFactory.newInstance();
                SAXParser saxParser = spf.newSAXParser();
                saxParser.parse(is,new XMLHandler(handler));
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

    }
}

新建一个xml数据解析的帮助类,


/**
 * 这个类是解析xml数据的帮助类
 */
public class XMLHandler extends DefaultHandler {

    //存储解析结果的集合
    private List<XmlBean> beans;
    //存储当前数值的对象
    private XmlBean currentbean;
    //存储当前xml标签的对象
    private String currentTag;
    private Handler handler;

    public XMLHandler(Handler handler) {
        //通过构造方法传来一个handler
        this.handler = handler;
    }

    //开始解析文件,xml文件的最外层做一些准备工作
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        //初始化
        beans = new ArrayList<>();
    }
    //element:元素
    //进入第一层,进入item

    /**
     * @param uri
     * @param localName  指的是本地标签(最外层的标签)
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if ("item".equals(localName)) {
            currentbean = new XmlBean();
        }
        //将方法传来的标签转移到本类定义的String上
        //这样我们才能通过currentTag来进行判断使用
        currentTag = localName;
    }

    //在这里才是正式的解析,分别判断 key是否对,获取value

    /**
     * @param ch     存储每一个标签内容的字节数据(char类型的数组)
     * @param start  开始的位置
     * @param length 总长度
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        //将传来的字节数据处理成字符串
        String str = new String(ch, start, length);
        if ("title".equals(currentTag)) {
            currentbean.setTitle(str);
        } else if ("image".equals(currentTag)) {
            currentbean.setImage(str);
        } else if ("description".equals(currentTag)) {
            currentbean.setDescription(str);
        }

    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);

        if ("item".equals(localName)) {
            beans.add(currentbean);
            currentbean = null;
        }
        currentTag = null;
    }

    //解析结束,将数据同handler发走,或加密
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        Message message = new Message();
        message.what = 102;
        message.obj = beans;
        handler.sendMessage(message);
    }
}

以上就是对xml解析的简单介绍,
本人菜鸟一个,有什么不对的地方希望大家指出评论,大神勿喷,希望大家一起学习进步!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值