pull解析器的简单示例

对xml的解析,我们在将j2ee中,常使用的解析器是DOM和SAX。而在android中,我们还可以使用PULL解析器。

pull是android中内置的解析器,可以直接的使用相关的类来解析大部分的xml文件了。pull也是采用事件驱动模型,跟SAX解析XML文件差不多。

xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<people>
<person id="001">
<name>XY1</name>
<age>22</age>
</person>
<person id="002">
<name>XY2</name>
<age>22</age>
</person>
</people> 
这个xml文件为了获取流的方便,我是放在src目录下的。

解析的具体方法:

public class XmlTest extends Activity {
	private InputStream in = null;
	private List<Person> list = null;
	private Person person = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 将xml文件转换为输入流
		in = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("people.xml");

		// 新建List集合,来存放person数据
		try {
			// 获取解析实例
			XmlPullParser xmlparser = XmlPullParserFactory.newInstance()
					.newPullParser();
			// 设置解析的xml
			xmlparser.setInput(in, "UTF-8");
			// 取得事件
			int event = xmlparser.getEventType();
			/*
			 * 开始循环解析xml里面的元素 当没到文档结束的位置,就一直循环下去
			 */
			while (event != XmlPullParser.END_DOCUMENT) {
				// 获取节点的名字
				String Node = xmlparser.getName();
				if (Node != null) {
					Log.i("Node", Node);
				} else {
					Log.i("Node", Node + "=null");
				}
				switch (event) {
				// 文档开始,即:<?xml version="1.0" encoding="UTF-8"?>
				case XmlPullParser.START_DOCUMENT:
					// 数据初始化
					list = new ArrayList<Person>();
					break;
				// 节点
				case XmlPullParser.START_TAG:
					//初始化对象。
					if ("person".equals(Node)) {
						person = new Person();
						person.setId(Integer.parseInt(xmlparser
								.getAttributeValue(0)));
					}
					//设置对象的姓名
					else if ("name".equals(Node)) {
						person.setName(xmlparser.nextText());
					} 
					//设置对象的年龄
					else if ("age".equals(Node)) {
						person.setAge(xmlparser.nextText());
					}
					break;
				// 结束节点
				case XmlPullParser.END_TAG:
					if ("person".equals(Node)) {
						list.add(person);
						person = null;
					}
					break;
				default:
					break;
				}
				// 继续下一个标签
				event = xmlparser.next();
			}
			Log.i("list", list.get(0).toString() + "**"
					+ list.get(1).toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
在上面的实例中,大家可以看到我在获取节点的时候,是打印了节点名字的,判断当节点获取为空的时候也会打印出来“Node=null”的字符窜。

我们来看下打印的日志:

pull解析器的简单示例_第1张图片

在最后的时候,打印的list集合是符合我们的原来xml数据。

但为啥每次节点都会多个空节点呢??

原来,在xml中标签和内容都可以叫做节点。而节点分为两类,一个是ElementNode(元素节点),一个是TextNode(文本节点)。而在我们的xml中,每个节点都是换了行的,虽然看起来什么也没有,但也是节点,是文本节点,里面有回车和空格。

也许我这样更能理解点,可以明显的看出每个节点之间是换行了的。

pull解析器的简单示例_第2张图片

那么该如何去纠正了??

1.修改xml的格式:

pull解析器的简单示例_第3张图片

可以看到效果:

在这,name和age就没有空节点了。

不过这样的方式,只能说是一种取巧了,因为你不可能把所有的xml都放在同一行吧。

我们如此在意这个空节点的原因是,每次运行到空节点的时候,都会循环遍历依次,消耗我们的资源。如果当遇到空节点的时候,不遍历是不是可以呢?

protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 将xml文件转换为输入流
		in = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("people.xml");

		// 新建List集合,来存放person数据
		try {
			// 获取解析实例
			XmlPullParser xmlparser = XmlPullParserFactory.newInstance()
					.newPullParser();
			// 设置解析的xml
			xmlparser.setInput(in, "UTF-8");
			// 取得事件
			int event = xmlparser.getEventType();
			// 初始化person对象
			person = new Person();
			// 初始化集合
			list = new ArrayList<Person>();
			/*
			 * 开始循环解析xml里面的元素 当没到文档结束的位置,就一直循环下去
			 */
			while (event != XmlPullParser.END_DOCUMENT) {

				// 获取节点的名字
				String Node = xmlparser.getName();
				if (Node != null) {
					// Log.i("Node", Node);
				} else {
					// Log.i("Node", Node + "=null");
					event = xmlparser.next();
					Node = xmlparser.getName();
				}
				switch (event) {
				// 文档开始,即:<?xml version="1.0" encoding="UTF-8"?>
				case XmlPullParser.START_DOCUMENT:
					break;
				// 节点
				case XmlPullParser.START_TAG:
					if ("person".equals(Node)) {
						// person=new Person();
						person.setId(Integer.parseInt(xmlparser
								.getAttributeValue(0)));
					}
					// 设置对象的姓名
					else if ("name".equals(Node)) {
						person.setName(xmlparser.nextText());
					}
					// 设置对象的年龄
					else if ("age".equals(Node)) {
						person.setAge(xmlparser.nextText());
					}
					break;
				// 结束节点
				case XmlPullParser.END_TAG:
					if ("person".equals(Node)) {
						list.add(person);
						person = new Person();
					}
					break;
				default:
					break;
				}
				if (Node != null) {
					Log.i("Node", Node);
				} else {
					Log.i("Node", Node + "=null");
				}
				// 继续下一个标签
				event = xmlparser.next();
			}
			Log.i("list", list.get(0).toString() + "," + list.get(1).toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

更改了初始化集合和对象的地方,在获取到null节点的时候,加了判断的语句。

pull解析器的简单示例_第4张图片

这就是效果图了,没有运行到null的节点了吧。

至于为啥,输出的集合元素中的有换行,那是因为解析的xml的字符窜中带有换行的字符。

你可能感兴趣的:(android,网络编程,实例)