【玩转Android-01】AndroidXML文件解析之Pull解析

一、Pull解析概述:

1.pull解析类似SAX解析,它们都采用事件驱动方式来进行解析。不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那

样由处理器触发一种事件的方法,执行我们的代码:读取到xml的声明返回 START_DOCUMENT 结束返回 END_DOCUMENT; 开始标签返回 START_TAG

结束标签返回 END_TAG; 文本返回 TEXT。

 

2.pull的工作原理:当pull解析器开始解析之后,开发者可以不断调用pull解析器的next()方法来获取下一个解析事件(开始文档、结束文档、开始标签、结束标签等)。当处于某

个元素时,可调用XmlPullParsergetAttributeValue()方法来获取该元素的属性值,也可调用XmlPullParsernextText()方法来获取该元素的属性值。当解析到一个文档结束

时,自动生成EndDocument事件。


二、Pull解析实例:


1.创建一个项目,项目名为XMLParserTest,主要文件如下图:



2.向项目中放入一个已经写好的books.xml文件,文件放入src目录下,便于类加载器快速加载

<?xml version="1.0" encoding="UTF-8" ?> 
   <books>
    <book id="001">
        <name>疯狂Android</name>
        <price>99.00</price>
    </book>
    <book id="002">
        <name>Thinking in Java</name>
        <price>101.00</price>
    </book>
    <book id="003">
        <name>疯狂Java</name>
        <price>70.50</price>
    </book>
</books>



3.在activity_main.xml中放入一个TextView显示解析结果和两个Button分别读取XML和写入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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.xmlparsertest.MainActivity" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="读取XML" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="写入XML" />

</LinearLayout>


4.创建解析Xml文件的业务类,名称为BookService,用于解析books.xml和创建新的xml文件

package com.example.service;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

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

import android.util.Xml;

import com.example.bean.Book;

/**
 * @author King.M.J
 */
public class BookService {

    // --------------------使用pull解析器解析books.xml文件---------------------

    public List<Book> getBooks(InputStream xmlfile) throws Exception { // 接收一个xml文件对象
	List<Book> books = null;
	Book book = null;
	XmlPullParser parser = Xml.newPullParser(); // 利用Android的xml工具类获取一个xml文件解析器
	parser.setInput(xmlfile, "utf-8"); // 解析文件,设置parser的字符集
	int event = parser.getEventType(); // 获取解析状态,返回的是int型数字状态
	while (event != XmlPullParser.END_DOCUMENT) {	//如果状态不是结束事件END_DOCUMENT,就继续往下解析
	    switch (event) {
	    case XmlPullParser.START_DOCUMENT:    //如果为开始解析头标签START_DOCUMENT,初始化数据
		books = new ArrayList<Book>();
		break;

	    case XmlPullParser.START_TAG:	 //如果为开始解析属性START_TAG,则获取数据
		if (parser.getName().equals("book")) {  //如果属性名对应XML文件中的节点名,则获取数据
		    book = new Book();		
		    
		  //调用XmlPullParser的getAttributeValue()方法来获取该元素的属性值
		    String id = parser.getAttributeValue(0);	
		    book.setId(id);
		} else if (parser.getName().equals("name")) {
			
		//调用XmlPullParser的nextText()方法来获取该元素的属性值
		    String name = parser.nextText();
		    book.setName(name);

		} else if (parser.getName().equals("price")) {
		    String price = parser.nextText();
		    book.setPrice(Double.parseDouble(price));

		}
		break;
		
		//当触发xml文档结束事件的名称为book(即解析结束位置),将封装对象放入集合,再将对象清空	
	    case XmlPullParser.END_TAG:			
		if (parser.getName().equals("book")) {
		    books.add(book);
		    book = null;
		}
		break;
	    }
	    event = parser.next();	// 保证解析器的指针向下移动
	}
	return books;

    }

    // --------------------通过pull接续器创建xml文档-----------------------

    public void saveXml(List<Book> books, OutputStream out) throws Exception {
	XmlSerializer serializer = Xml.newSerializer();    //创建xml的序列化文件
	serializer.setOutput(out, "utf-8");		     //传入保存的输出流,和字符集编码
	serializer.startDocument("utf-8", true);	//xml头标签字符集设置,是否序列化
	serializer.startTag(null, "books");		//开始节点设置,(命名空间null,名称books)
	for (Book book : books) {		    //循环设置每个节点的属性和数据
	    serializer.startTag(null, "book");
	    serializer.attribute(null, "id", book.getId());

	    serializer.startTag(null, "name");
	    serializer.text(book.getName());
	    serializer.endTag(null, "name");

	    serializer.startTag(null, "price");
	    serializer.text(book.getPrice() + "");
	    serializer.endTag(null, "price");

	    serializer.endTag(null, "book");
	}

	serializer.endTag(null, "books");   //设置结束节点
	serializer.endDocument();		//结束xml编辑,即设置xml文档结尾
	out.flush();
	out.close();									

    }
}


5.创建Book的javaBean,用于存放从books.xml中解析出来的数据,注意生成其对应的geter()与seter()方法,同时重写一下toString()便于输出

package com.example.bean;

/**
 * Book的Model类,用于存放从books.xml中解析出来的数据。重写了toString方法便于输出
 * 
 * @author King.M.J
 */
public class Book {
    private String id;
    private String name;
    private double price;

    public Book() {
	super();
    }

    public Book(String id, String name, double d) {
	this.id = id;
	this.name = name;
	this.price = d;
    }

    public String getId() {
	return id;
    }

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

    public String getName() {
	return name;
    }

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

    public double getPrice() {
	return price;
    }

    public void setPrice(double price) {
	this.price = price;
    }

    @Override
    public String toString() {

	return "图书编号:" + id + "\n图书名称:" + name + "\n图书价格:" + price + "\n";
    }

}


6.在MainActivity.java中设置事件的监听

package com.example.xmlparsertest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.bean.Book;
import com.example.service.BookService;

/**
 * Pull解析器,这里定义了一个TextView显示解析结果和两个Button
 * 
 * @author King.M.J
 * 
 */
public class MainActivity extends Activity {
    private static final String TAG = "XML"; // 定义一个TAG,便于在LogCat中过滤出消息
    private TextView text = null;
    private Button readXML = null;
    private Button writeXML = null;

    private BookService bookService;		//声明一个BookService对象
    private List<Book> booksList;			

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	text = (TextView) findViewById(R.id.text);
	readXML = (Button) findViewById(R.id.button1);   //读取XML按钮
	writeXML = (Button) findViewById(R.id.button2);  //写入XML按钮	

	readXML.setOnClickListener(new OnClickListener() {

	    @Override
	    public void onClick(View v) {
		InputStream in = getClass().getClassLoader()	//得到books.xml文件
			.getResourceAsStream("books.xml");
		bookService = new BookService();
		try {
		    booksList = bookService.getBooks(in);
		    for (Book book : booksList) {
			Log.i(TAG, book.toString());
			text.setText(text.getText() + book.toString());

		    }

		} catch (Exception e) {
		    Log.e(TAG, e.getMessage());
		}

	    }
	});

	writeXML.setOnClickListener(new OnClickListener() {

	    @Override
	    public void onClick(View arg0) {
		booksList = new ArrayList<Book>();
		Book b1 = new Book("101", "疯狂HTML5", 82.5);
		Book b2 = new Book("102", "轻量级JavaEE", 100.5);
		Book b3 = new Book("103", "疯狂AJAX", 70.5);
		booksList.add(b1);
		booksList.add(b2);
		booksList.add(b3);

		// books.xml文件保存在 /data/data/<当前应用包>/files目录下
		try {
			File xmlFile=new File(MainActivity.this.getFilesDir(),"books.xml");
		    FileOutputStream out = new FileOutputStream(xmlFile);
		    bookService.saveXml(booksList, out);
		    Toast.makeText(getApplicationContext(), "成功生成books.xml", 1).show(); 

		} catch (Exception e) {

		    Log.e(TAG, e.getMessage());
		}

	    }
	});

    }

}

7.运行结果,写入XML后可以在FileExplorer中data/data/com.example.xmlparsertest/files中看到books.xml,导出后查看里面的内容,如图:




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值