android中用xmlpullparser解析xml文件,以及res/raw和assets的不同

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android中用xmlpullparser解析xml文件,以及res/raw和assets的不同相关的知识,希望对你有一定的参考价值。

参考技术A

 XML:可扩展标记语言
读XML,XML文件的解析  

三种解析XML的文件的方式
1. SAX       事件驱动   不是一次性加载到内存
2. DOM       一次加载到内存,性能较差   适合服务器端编程
3. XMLPULL   适应嵌入式设备,占用内存较小   API相对简单

OpenAPI

JSON: 相对于XML格式,更节省空间。
1) 大括号开始结束
2) 内容部分每条数据以“,”分隔
3) 每条数据由键值对构成,key必须是字符串“”
4) 值可以是:String、double、int、long、boolean、
             jsonObject、jsonArray

把要解析的XML文件放在assets目录下,这里解释下

res/raw和assets的相同点:
    两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。




res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹




读取文件资源:
1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作
·        InputStream is =getResources().openRawResource(R.id.filename);  
2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作
·        AssetManager am = null;  
·        am = getAssets();  
·        InputStream is = am.open("filename");  




注意1:Google的android系统处理Assert有个bug,在AssertManager中不能处理单个超过1MB的文件,不然会报异常,raw没这个限制可以放个4MB的Mp3文件没问题。

注意2:assets 文件夹是存放不进行编译加工的原生文件,即该文件夹里面的文件不会像 xml, java 文件被预编译,可以存放一些图片,html,js, css 等文件。




解析如下文件






1

2

3

4

5

6

7





<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentRight="true"

android:layout_alignTop="@+idtton1"

android:text="Large Text"

android:textAppearance="?android:attr/textAppearanceLarge" /> 





代码如下:






1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20 



XmlPullParser pullParser = Xml.newPullParser();//得到XML解析器

AssetManager assetManager = getAssets();//文件保存在assets目录下,得到assetManager管理器

InputStream is;

try



    is = assetManager.open("activity_main.xml");//打开文件,得到输入流

    pullParser.setInput(is , "utf-8");// String inputEncoding格式

    int eventType = pullParser.getEventType();//得到事件类型

    while(eventType != XmlPullParser.END_DOCUMENT)//文档的末尾

    //遍历内部的内容

        String name = pullParser.getName();

        if("TextView".equals(name))

        

            String value = pullParser.getAttributeValue(2);//得到属性值(位置)

            textView.setText("显示结果为:" + value);

            break;/到就返回

        

        eventType = pullParser.next();//读取下一个标签

    

 


显示结果为:

XmlPullParser 与 XmlSerializer

 

XmlSerializer与XmlPullParser的使用实践:

先贴代码:

1.利用eclipse生成一个默认的工程;

2.修改布局文件activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/btn_product"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="生成XML" />

    <Button
        android:id="@+id/btn_pull"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="解析XML" />

</LinearLayout>

3.MainActivity.java修改

package com.example.testxml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import android.R.integer;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.util.Log;
import android.util.Xml;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

    private Button btn_product;
    private Button btn_pull;
    private List<Person> personInfo = null;

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

        btn_product = (Button) findViewById(R.id.btn_product);
        btn_pull = (Button) findViewById(R.id.btn_pull);

        btn_product.setOnClickListener(this);
        btn_pull.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

        switch (v.getId()) {
        case R.id.btn_product:
            String exState = Environment.getExternalStorageState();
            if (Environment.MEDIA_MOUNTED.equals(exState)) {
                File exDirectory = Environment.getExternalStorageDirectory();
                saveToSdCard(exDirectory + "/test.xml");
            } else {
                return;
            }

            break;
        case R.id.btn_pull:

            String exState1 = Environment.getExternalStorageState();
            if (Environment.MEDIA_MOUNTED.equals(exState1)) {
                File exDirectory = Environment.getExternalStorageDirectory();
                getXmlInfo(exDirectory + "/test.xml");

                for (Person i : personInfo) {
                    Log.i("TAG", i.toString());
                }

            } else {
                return;
            }

            break;
        }
    }

    private void getXmlInfo(String dir) {
        // TODO Auto-generated method stub

        try {
            Person person = null;
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            XmlPullParser xpp = factory.newPullParser();
            FileInputStream input = new FileInputStream(dir);

            xpp.setInput(input, "UTF-8");
            int eventType = xpp.getEventType();

            while (XmlPullParser.END_DOCUMENT != eventType) {

                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    personInfo = new ArrayList<Person>();
                    break;
                case XmlPullParser.START_TAG:
                    if ("Persons".equals(xpp.getName())) {

                    } else if ("person".equals(xpp.getName())) {
                        person = new Person();
                        String attri = xpp.getAttributeName(0); // 获取属性名称
                        if ("id".equals(attri)) {
                            String id = xpp.getAttributeValue(0); // 获取属性名称的值
                            person.setId(id);
                        }
                    } else if ("name".equals(xpp.getName())) {

                        person.setName(xpp.nextText());
                    } else if ("age".equals(xpp.getName())) {

                        person.setAge(xpp.nextText());
                    } else if ("score".equals(xpp.getName())) {
              //实际就是把xpp.nextText拆分成了两步而已
                        xpp.next();
                        if (xpp.getEventType() == XmlPullParser.TEXT)
                            person.setScore(xpp.getText());
                    }
                    break;
                case XmlPullParser.END_TAG:

                    if ("person".equals(xpp.getName())) {
                        personInfo.add(person);
                    }
                    break;
                }

                eventType = xpp.next();
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private void saveToSdCard(String dir) {
        // TODO Auto-generated method stub

        XmlSerializer xml = Xml.newSerializer();
        try {
            int i;
            FileOutputStream ouput = new FileOutputStream(dir);
            xml.setOutput(ouput, "UTF-8");

            xml.startDocument(null, true);

            xml.startTag(null, "Persons");

            for (i = 0; i < 10; i++) {
                xml.startTag(null, "person");
                xml.attribute(null, "id", Integer.toString(i));

                xml.startTag(null, "name");
                xml.text("张" + i);
                xml.endTag(null, "name");

                xml.startTag(null, "age");
                xml.text("10" + i);
                xml.endTag(null, "age");

                xml.startTag(null, "score");
                xml.text("60" + i * 2);
                xml.endTag(null, "score");

                xml.endTag(null, "person");
            }

            xml.endTag(null, "Persons");

            xml.endDocument();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

4.Person.java

package com.example.testxml;

public class Person {

    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    private String name;
    private String age;
    private String score;

    public Person() {
        name = null;
        age = null;
        score = null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getScore() {
        return score;
    }

    public void setScore(String score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", score=" + score
                + "]";
    }

}

 

实践过程中遇到的问题:

1.XmlPullParser解析器的内容获取:

XmlPullParser.START_DOCUMENT :XML解析的开始标志<?xml version="1.0" encoding="UTF-8" standalone="true"?>

XmlPullParser.START_TAG :节点标签 <Persons>

XmlPullParser.END_TAG: 节点结束标签</Persons>

XmlPullParser.TEXT :节点之间内容的标签 <age>100</age>也就是100这个内容值;具体使用详见上面代码;

XmlPullParser.END_DOCUMENT: XML解析结束标志</Persons>“ ”,引号之间存在一个结束的内容;

2.ArrayList当中内容存储的方式:

List<Person> personInfo = new ArrayList<Person>()

通过personInfo.add(person)去添加内容到数组列表时,person添加到数组并非像C当中一样将内容拷贝到数组列表,而类似于指针建立了一个指向关系;

因此如果每次添加的person都是同一个,那么数组列表中的内容值会被替换成最后添加的内容;

 

以上是关于android中用xmlpullparser解析xml文件,以及res/raw和assets的不同的主要内容,如果未能解决你的问题,请参考以下文章

如何使用xmlpullparser解析android中的汉字

Android:DOM vs SAX vs XMLPullParser 解析?

XmlPullParser - 意外令牌(android)

Android XmlPullParser UTF-8 问题

Android--数据解析

XML的XmlPullParser解析