安卓开发xm解析

小菜鸟我使用的是android studio

Eclipse下libs里添加org.apache.http.legacy.jar

网络请求是已经被谷歌抛弃的httpclient,当然也可以使用Google比较喜欢的httpurlconnection.以下我是以httoclient为例,

首先是 在项目中的build.app中设置添加如下在代码useLibrary 'org.apache.http.legacy'
在android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.wk620xml.wk620xml"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    useLibrary 'org.apache.http.legacy'
}有可能会报错。可以如下操作

HttpClient虽然已经被Google抛弃,但是有限项目依然依赖这些库,还得用。我把Httpclient的所有库导入项目后,会产生如下错误。

Error:duplicate files during packaging of APK F:\Downloads\MyApplication7\app\build\outputs\apk\app-debug-unaligned.apk

Path in archive: META-INF/DEPENDENCIES

Origin 1: F:\Downloads\MyApplication7\app\libs\httpclient-4.5.2.jar

Origin 2: F:\Downloads\MyApplication7\app\libs\httpcore-4.4.4.jar

经过查找可以在文件中加入以下代码消除这个问题。

 

  1. packagingOptions {  
  2.     exclude 'META-INF/DEPENDENCIES'  
  3.     exclude 'META-INF/NOTICE'  
  4.     exclude 'META-INF/LICENSE'  
  5.     exclude 'META-INF/LICENSE.txt'  
  6.     exclude 'META-INF/NOTICE.txt'  
  7.     exclude 'META-INF/ASL2.0'  
  8.     exclude 'META-INF/notice.txt'  
  9. }
对于xml解析需要我们自己建小型服务器  我们可以使用Apache服务器安装包,当然也可以有其他选择,下载地址:http://httpd.apache.org/download.cgi

安装方法是一直点击下一步。会提示输入自己的域名,这个可以随便填,到选择安装路径的时候,可以默认路径,安装完成后可以在浏览器地址栏中输入127.0.0.1,可以弹出页面说明我们的服务器已经启动成功,接着进入到Apachede安装目录下,小菜鸟是在c:\Apache\Apache2\htdocs目录下,我们可以新建一个文件夹get_date,编辑文件

编辑代码如下:

<apps>

    <app>

        <id>1</id>

        <name>google11111</name>

        <vesion>1.0</vesion>
    </app>

    <app>

        <id>2</id>

        <name>google22222</name>

        <vesion>2.0</vesion>
    </app>

    <app>

        <id>3</id>

        <name>google333333</name>

        <vesion>3.0</vesion>
    </app>
</apps>

服务器的准备工作结束,当然可以使用android studio中的自带布局那块的属性,直接编辑一个本地服务器进行解析

// TODO: 2017-06-20 pull解析  吴凯 
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //这是pull解析
    private void sendRequestWithHttpClient() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    HttpClient httpClient = new DefaultHttpClient();
                    //指定访问的服务器地址是电脑本机
                    HttpGet httpGet = new HttpGet("http://10.2.2/get_date.xml");
                    HttpResponse httpResponse = httpClient.execute(httpGet);
                    //因为http请求的响应时间确定是否响应成功
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        //请求和相应成功
                        HttpEntity entity = httpResponse.getEntity();
                        String response = EntityUtils.toString(entity, "utf-8");
                        parseXMLwithPull(response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void parseXMLwithPull(String xml) {
        try {
            //XmlPullParserFactory首先是获取实例
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            //利用实例调用setinput将数据写进去
            XmlPullParser xmlPullParser = factory.newPullParser();
            xmlPullParser.setInput(new StringReader(xml));
            //通过调用此方法得到当前解析事件
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String version = "";
            while (eventType != xmlPullParser.END_DOCUMENT) {
                String nodename = xmlPullParser.getName();
                switch (eventType) {
                    case XmlPullParser.START_TAG: {
                        //开始解析某个节点
                        if ("id".equals(nodename)) {
                            try {
                                id = xmlPullParser.nextText();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } else if ("name".equals(nodename)) {
                            try {
                                name = xmlPullParser.nextText();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } else if ("version".equals(nodename)) {
                            try {
                                version = xmlPullParser.nextText();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        break;
                    }
                    //完成解析某个节点
                    case XmlPullParser.END_TAG: {
                        if ("app".equals(nodename)) {
                            Log.e("mainactivity", "id====" + id);
                            Log.e("mainactivity", "name===" + name);
                            Log.e("mainactivity", "version===" + version);

                        }
                        break;
                    }
                    default:
                        break;
                }
                try {
                    eventType = xmlPullParser.next();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
    }

}
 --------------------------------------------------------------------------------
以上是pull解析
接下来写一个简单的sax解析
首先需要写一个方法继承defaulthandler
// TODO: 2017-06-20 sax解析  吴凯
public class MyHandler extends DefaultHandler {
    private String nodename;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;

    //xml解析时候会调用
    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
//        super.startDocument();
    }

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

    //xml获取某个节点时候会调用
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        //根据当前节点名判断将内容添加到哪一个stringbuilder对象中
        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);
        }
//        super.characters(ch, start, length);
    }

    //xml完成某个节点时候调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("app".equals(localName)) {
            Log.e("myhander", "id====" + id.toString().trim());
            Log.e("myhander", "name===" + name.toString().trim());
            Log.e("myhander", "version===" + version.toString().trim());
            //最后将stringbuidler清空掉
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }

//        super.endElement(uri, localName, qName);
    }

    //xml解析完成整个节点时候调用
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }
}
=========================
在mainactivity操作
// TODO: 2017-06-20 pull解析  吴凯 
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //这是pull解析
    private void sendRequestWithHttpClient() {
        new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    HttpClient httpClient = new DefaultHttpClient();
                    //指定访问的服务器地址是电脑本机
                    HttpGet httpGet = new HttpGet("http://10.2.2/get_date.xml");
                    HttpResponse httpResponse = httpClient.execute(httpGet);
                    //因为http请求的响应时间确定是否响应成功
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        //请求和相应成功
                        HttpEntity entity = httpResponse.getEntity();
                        String response = EntityUtils.toString(entity, "utf-8");
                        parsexmlsax(response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private void parsexmlsax(String xml) {

        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlreader = factory.newSAXParser().getXMLReader();
            MyHandler handler = new MyHandler();
            //myhandler实例设置进入xmlreader
            xmlreader.setContentHandler(handler);
            //开始执行解析
            try {
                xmlreader.parse(new InputSource(new StringReader(xml)));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

}
//总结
最后分析下xml解析dom,pull,sax三种的区别,以及优缺点

1DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,把整个xml数据加载进去

2SAX是基于事件驱动的。、边加载边解析

3SAX方式是基于事件驱动的。、PULL方式读xml回调方法返回的是数字。

边加载边解析

   读取到xml的声明返回 START_DOCUMENT;

   读取到xml的结束返回 END_DOCUMENT ;

   读取到xml的开始标签返回 START_TAG

   读取到xml的结束标签返回 END_TAG

   读取到xml的文本返回  TEXT



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值