Android之DOM解析XML

DOM方式解析XML是先把XML文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的。如果XML文件很大的时候,处理效率就会变的很低。

用DOM解析的具体思路是:

1.将XML文件加载进来。

2.获取文档的根节点。

3.获取文档根节点中所有子节点的列表。

4.获取子节点列表中需要读取的信息。

插曲:补充一些DOM API的知识,有助于大家理解(其实和JS里找元素节点一样):

nodeName 某个节点的名称。
元素节点的 nodeName 是元素名称
属性节点的 nodeName 是属性名称
文本节点的 nodeName 永远是 #text
文档节点的 nodeName 永远是 #document

nodeValue 节点里的值
对于文本节点,nodeValue 属性包含文本。

对于属性节点,nodeValue 属性包含属性值。

nodeType 属性可返回节点的类型
元素element返回1
属性attr 返回2
文本text返回3
注释comments返回8
文档document 返回9

Demo:

服务放的XML数据:

Android之DOM解析XML_第1张图片

这里我是用自己电脑上的Tomcat搭建的服务器,文件存放地址:TomCat安装目录/Tomcat7.0/webapps/ROOT/get_data.xml.

实现效果:

Android之DOM解析XML_第2张图片

(1)activity_main.xml文件




    

(2)MainActivity.java

package com.example.xmlanddom;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    public final static String TAG = "XMLParseDom";

    private TextView response_text;

    private StringBuilder msg=new StringBuilder();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        response_text = (TextView) this.findViewById(R.id.response_text);
    }

    public void click(View v) {
        sendRequestWithHttpURLConnection();
    }

    /**
     * 开启线程向服务器读取数据
     */
    public void sendRequestWithHttpURLConnection() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("http://10.0.2.2:8080/get_data.xml")
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    parseXMLWithDOM(responseData.trim());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void parseXMLWithDOM(String xmlData) {
        try {
            //创建DOM工厂对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //通过DOM工厂创建DocumentBuilder
            DocumentBuilder builder = factory.newDocumentBuilder();
            //将数据转换成InputStream
            InputStream is = new ByteArrayInputStream(xmlData.getBytes());
            //把输入流转换成DOM对象
            Document document = builder.parse(is);
            //获取根节点
            Element root = document.getDocumentElement();
            //解析XML文件
            parse(root);
            showResponseToUI(msg.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 用Document方法解析XML
     *
     * @param element 将要进行遍历的节点
     */
    private void parse(Element element) {
        String id = "";
        String name = "";
        String version = "";
        //得到element元素的所有子元素
        NodeList nodeList = element.getChildNodes();
        int size = nodeList.getLength();
        for (int i = 0; i < size; i++) {
            //获取特定位置的node
            Node element2 = (Node) nodeList.item(i);
            //得到element2节点的名称
            String tagName = element2.getNodeName();
            Log.i(TAG, "节点的类型为:" + element2.getNodeType() + ",节点的名字为:" + tagName);
            if (tagName.equals("app") && element2.getNodeType() == Document.ELEMENT_NODE) {
                if (element2.getNodeType() == Document.ELEMENT_NODE) {
                    //如果element2还有子节点,递归解析子节点
                    parse((Element) element2);
                }
            }
            if (tagName.equals("id")) {
                id = element2.getTextContent();
                Log.i(TAG, id);
            }
            if (tagName.equals("name")) {
                name = element2.getTextContent();
                Log.i(TAG, name);
            }
            if (tagName.equals("version")) {
                version = element2.getTextContent();
                Log.i(TAG, version);
            }
        }
        if(id!=""&&name!=""&&version!="") {
            msg.append("id=" + id + ",name=" + name + ",version=" + version + ";\n");
        }
        Log.i(TAG, id + name + version);
    }

    private void showResponseToUI(final String response){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                //在这里进行UI操作,将结果显示到界面上
                response_text.setText(response);
            }
        });
    }

}
(3)build.gradle

网络请求用的是OKHttp,所以要在gradle中加入依赖。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
}

(4)AndroidManifest.xml

  

Dom解析XMl过程:

Android之DOM解析XML_第3张图片

Android之DOM解析XML_第4张图片

其实就是用递归的方法对树形结构XMl文档进行读取。

你可能感兴趣的:(android学习笔记)