Android初级开发(九)——网络交互—解析XML格式数据

一、前言

首先我们先搭建一个web服务器,我这里用的是tomcat,搭建过程可参见tomacat服务器的搭建:http://blog.csdn.net/qq_28585471/article/details/77449526。然后在这个服务器下提供一段XML文本,然后,我们在这个程序里去访问这个服务器,再对得到的XML文本进行解析。

这里写图片描述
文本内容为:
这里写图片描述

我们可以在网页中输入地址预览一下:

这里写图片描述

预览成功说明tomcat成功连接,且文本设置正确。

二、 PULL解析
我们在OkHttp的项目上进行修改,布局文件不用变,修改MainActivity.java就可以

public class MainActivity extends AppCompatActivity {

    Button sendRequest;
    TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        responseText = (TextView) findViewById(R.id.response_text);
        sendRequest = (Button) findViewById(send_request);
        sendRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try{
                            OkHttpClient client = new OkHttpClient();
                            //将HTTP请求的地址改为http://10.0.2.2:8080/zwj/zwj.xml
                            //模拟器是连接不到localhost的,10.0.2.2对于模拟器来说就是电脑本机的IP地址
                            Request request = new Request.Builder().url("http://10.0.2.2:8080/zwj/zwj.xml").build();
                            Response response = client.newCall(request).execute();
                            String responseData = response.body().string();
                            //得到服务器返回的数据后,调用parseXMLWithPull()方法解析服务器返回的数据
                            parseXMLWithPull(responseData);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });
    }

    private void parseXMLWithPull(String xmlData) {
        try{
            //首先获取一个XmlPullParserFactory实例
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            //借助这个XmlPullParserFactory实例得到XmlPullParser对象
            XmlPullParser xmlPullParser = factory.newPullParser();
            //调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去
            xmlPullParser.setInput(new StringReader(xmlData));
            //开始解析
            //通过getEventType得到当前的解析事件
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String version = "";
            //在一个while循环中不断地进行解析
            //如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析工作还未完成,调用next()方法后获取下一个解析事件
            while (eventType != XmlPullParser.END_DOCUMENT){
                String nodeName = xmlPullParser.getName();
                switch (eventType){
                    //开始解析某个节点
                    case XmlPullParser.START_TAG:{
                        if("id".equals(nodeName)){
                            id = xmlPullParser.nextText();
                        }else if ("name".equals(nodeName)){
                            name = xmlPullParser.nextText();
                        }else if ("version".equals(nodeName)){
                            version = xmlPullParser.nextText();
                        }
                        break;
                    }
                    //完成解析某个节点
                    case XmlPullParser.END_TAG:{
                        if("app".equals(nodeName)){
                            Log.d("MainActivity","id is" + id);
                            Log.d("MainActivity","name is" + name);
                            Log.d("MainActivity","version is" + version);
                        }
                        break;
                    }
                    default:
                        break;
                }
                eventType = xmlPullParser.next();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

看一下打印的日志:
这里写图片描述

解析成功啦~
那就再看一下SAX解析吧!


三、SAX解析
1、首先新建个ContentHandler类继承自DefaultHandler,并重写父类的5个方法

public class ContentHandler extends DefaultHandler {

    private String nodeName;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;


    /**
     * 在开始XML解析的时候调用
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    /**
     * 在开始解析某个节点的时候调用
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //记录当前节点名
        nodeName = localName;
    }

    /**
     * 在获取节点内容的时候调用
     * @param ch
     * @param start
     * @param length
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        //根据当前的节点名判断内容添加到哪一个StringBulider对象中
        if("id".equals(nodeName)){
            id.append(ch,start,length);
        }else if("name".equals(nodeName)){
            name.append(ch,start,length);
        }else if ("version".equals(nodeName)){
            version.append(ch,start,length);
        }
    }

    /**
     * 在完成解析某个节点的时候调用
     * @param uri
     * @param localName
     * @param qName
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("app".equals(localName)){
            Log.d("ContentHandler","id is" + id.toString().trim());
            Log.d("ContentHandler","name is" + name.toString().trim());
            Log.d("ContentHandler","version is" + version.toString().trim());
            //最后要将StringBuilder清空掉
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

    /**
     * 在完成整个XML解析的时候调用
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
}

这里我们首先给id,name,version节点分别定义了一个StringBuilder对象,并在startDocument()方法里对它们进行了初始化;每当开始解析某个节点的时候,startElement()方法就会得到调用,其中localName参数记录着当前节点的名字。接着在解析节点中具体内容的时候就会调用character()方法,然后我们根据当前节点名进行判断、将解析出的内容添加到哪一个StringBuilder对象中。最后在endElement()方法中进行判断,如果app节点已经解析完成,就打印出id,name,version的内容。打印完成后,要将StringBuilder的内容清空掉。

2、修改MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button sendRequest;
    TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        responseText = (TextView) findViewById(R.id.response_text);
        sendRequest = (Button) findViewById(R.id.send_request);
        sendRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try{
                            OkHttpClient client = new OkHttpClient();
                            //将HTTP请求的地址改为http://10.0.2.2:8080/zwj/zwj.xml
                            //模拟器是连接不到localhost的,10.0.2.2对于模拟器来说就是电脑本机的IP地址
                            Request request = new Request.Builder().url("http://10.0.2.2:8080/zwj/zwj.xml").build();
                            Response response = client.newCall(request).execute();
                            String responseData = response.body().string();
                            //得到服务器返回的数据后,调用parseXMLWithPull()方法解析服务器返回的数据
                            parseXMLWithSAX(responseData);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });
    }

    private void parseXMLWithSAX(String xmlData) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            ContentHandler handler = new ContentHandler();
            //将ContentHandler的实例设置到XMLReader中
            xmlReader.setContentHandler(handler);
            //开始执行解析
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

我们调用parseXMLWithSAX()方法来解析XML数据,首先创建一个SAXParserFactory对象,然后再获取到XMLReader对象,接着将ContentHandler实例设置到XMLReader中,最后调用parse()方法开始执行解析。

3、看一下logcat中的日志
这里写图片描述

和PULL解析一样的效果~~解析成功!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值