java学习篇(三)---dom.sax.pull解析浅谈

XML的解析

 

XML结构示意图:

<?xmlversion="1.0" encoding="UTF-8"?>

<persons>

<personid="23">

         <name>jack</name>

         <age>30</age>

</person>

<personid="20">

         <name>rose</name>

         <age>25</age>

</person>

</persons>

 

Ø XML的结构解析如下:

Ø 1、节点

Ø 2、元素

Ø 3、属性和属性值

Ø 由于XML的扩展性强,致使它需要有稳定的基础规则来支持扩展,该语法规则是:

Ø 1、开始和结束标签匹配

Ø 2、嵌套标签不能互相嵌套

Ø 3、区分大小写

 

Java解析XML的三种方式

Ø Android中,解析Xml数据的三种方式:

Ø 1DOM(org.w3c.dom)

Ø 文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。

Ø 2SAX(org.xml.sax)

Ø SimpleAPI for XML,以事件的形式通知程序,对Xml进行解析。

Ø 3XMLPULL(org.xmlpull.v1)

Ø 类似于SAX方式,程序以“拉取”的方式对Xml进行解析。

 

SAX是一种以事件驱动的XML api,由它定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,简单的讲,它解析速度快,占用内存少的解析器。这种解析器比较适合android 等移动设备。

使用SAX的优点是:

因为SAX的优势是流的方式处理,当遇到一个标签的时候,并不会记录下当前所碰到的标签。

也就是说,startEelment方法中,你所知道的信息,仅仅是当前的签名的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元素与其他结构相关的信息,都是不知道的。

代码:

package com.nsz.saxparser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyHandler extends DefaultHandler {
	
	private HashMap<String, String> map = null;  //存储单个解析的完整对象
	private List<HashMap<String, String>> list = null;  //存储所有的解析对象
	private String currentTag = null;  //正在解析的元素的标签
	private String currentValue = null;  //解析当前元素的值
	private String nodeName = null;  //解析当前的节点名称
	
	public MyHandler(String nodeName) {
		super();
		this.nodeName = nodeName;
	}

	public List<HashMap<String, String>> getList() {
		return list;
	}
	
	/**
	 * 当读到第一个开始标签的时候,会触发这个方法
	 */
	@Override
	public void startDocument() throws SAXException {
		list = new ArrayList<HashMap<String, String>>();
	}
	
	/**
	 * 当遇到文档的开头的时候,调用这个方法
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if(qName.equals(nodeName)){
			map = new HashMap<String, String>();
		}
		if(attributes != null && map != null){
			for (int i = 0; i < attributes.getLength(); i++) {
				String tagAttr = attributes.getQName(i);
				String tafAttrValue = attributes.getValue(i);
				map.put(tagAttr, tafAttrValue);
			}
		}
		currentTag = qName;
	}
	
	/**
	 * 这个方法是用来处理xml文件所读取到的内容
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		if(currentTag != null && map != null){
			currentValue = new String(ch, start, length);
			if(currentValue != null && !currentValue.trim().equals("")
					&& !currentValue.trim().equals("\n")){
				map.put(currentTag, currentValue);
			}
		}
		currentTag = null;  // 把当前的节点的对应的值和标签设置为空
		currentValue = null;
	}
	
	/**
	 * 遇到结束标记的时候,会调用这个方法
	 */
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if(qName.equals(nodeName)){
			list.add(map);
			map = null;
		}
		super.endElement(uri, localName, qName);
	}
	
}

package com.nsz.saxparser;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 联网请求访问对象
 * @author TF
 *
 */
public class HttpUtils {
	
	public static InputStream getXML(String path){
		InputStream inputStream = null;
		try {
			URL url = new URL(path);
			if(url != null){
				HttpURLConnection connection = (HttpURLConnection) url.openConnection();
				connection.setConnectTimeout(5000);
				connection.setDoInput(true);
				connection.setRequestMethod("GET");
				int code = connection.getResponseCode();
				if(code == 200){
					inputStream = connection.getInputStream();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return inputStream;
	}
}

package com.nsz.saxparser;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class SAXService {
	
	public static List<HashMap<String, String>> readXML(InputStream inputStream, String nodeName){
		try {
			// 创建一个解析xml的工厂对象
			SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
			// 解析xml
			SAXParser saxParser = saxParserFactory.newSAXParser();
			
			MyHandler myHandler = new MyHandler(nodeName);
			saxParser.parse(inputStream, myHandler);
			inputStream.close();
			return myHandler.getList();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}
测试
package com.nsz.saxparser;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;

public class Test {
	
	public static void main(String[] args) {
		String path = "http://localhost:8080/test/person.xml";
		InputStream in = HttpUtils.getXML(path);
		try {
			List<HashMap<String, String>> list = SAXService.readXML(in, "person");
			for (HashMap<String, String> map : list) {
				System.out.println(map.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

PULL技术介绍

除了可以使用以上两种解析XML文件之外,我们也可以使用Java自带的PULL来解析XML文件。

PULL解析器的运行方式和sax解析器很相似,它提供了类似的事件。

如开始元素和结束元素,使用parser.next()可以进行下一个元素并且触发相应的事件,事件将作为代码被发送,因此可以使用一个switch来对事件进行选择,然后进行相应的处理。当开始解析元素时候,调用parser.nextText()方法可以获得下一个Text类型的元素。

PULL特点:

简单的结构:一个接口,一个例外,一个工厂组成的PULL解析器

简单易用:PULL解析器只有一个重要的方法next方法,他被用来检索下一个事件,而它只有5个常用的属性:

START DOCUMENT

START_TAG

TEXT

END_TAG

END_DOCUMENT

代码:

<span style="font-size:14px;">package com.nsz.pullparser;

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

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

/**
 * 主要是使用PULL解析xml
 * @author TF
 *
 */
public class PullXMLTools {
	
	public static List<Person> parseXML(InputStream inputStream, String encode) throws Exception{
		List<Person> list = null;
		Person person = null;  //装载解析每一个person节点的内容
		// 创建一个xml解析的工厂
		XmlPullParserFactory xmlPullParserFactory = XmlPullParserFactory.newInstance();
		// 获得xml解析类的引用
		XmlPullParser parser = xmlPullParserFactory.newPullParser();
		parser.setInput(inputStream, encode);
		
		// 获得事件的类型
		int eventType = parser.getEventType();
		while(eventType != XmlPullParser.END_DOCUMENT){
			
			switch (eventType) {
			case XmlPullParser.START_DOCUMENT:
				list = new ArrayList<Person>();
				break;

			case XmlPullParser.START_TAG:
				if("person".equals(parser.getName())){
					person = new Person();
					// 取出属性值
					int id = Integer.parseInt(parser.getAttributeValue(0));
					person.setId(id);
				}else if("name".equals(parser.getName())){
					String name = parser.nextText();  // 获取该节点的内容
					person.setName(name);
				}else if("age".equals(parser.getName())) {
					int age = Integer.parseInt(parser.nextText());
					person.setAge(age);
				}
				break;
				
			case XmlPullParser.END_TAG:
				if ("person".equals(parser.getName())) {
					list.add(person);
					person = null;
				}
				break;
			}
			eventType = parser.next();
		}
		
		return list;
	} 
}

测试
package com.nsz.pullparser;

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

import android.test.AndroidTestCase;

public class Test extends AndroidTestCase{
	
	public static void test() {
		String path = "http://localhost:8080/test/person.xml";
		InputStream inputStream = HttpUtils.getXML(path);
		List<Person> list = null;
		try {
			list = PullXMLTools.parseXML(inputStream, "utf-8");
			for (Person person : list) {
				System.out.println(person.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
</span>

DOM技术介绍

DOM是一种用于XML文档对象模型,可用于直接访问XML文档的各个部位,在DOM中文档被模拟为树状,其中XML语法的每一个组成部分都表示一个节点,DOM允许用户遍历文档树,从父节点移动到子节点和兄弟节点。并利用某节点类型特有的属性(元素具有属性,文本节点具有文本数据)

节点(XML文档中的每一个成分都是一个节点)

DOM是这样规定的:

整个文档是一个节点文档

每一个XML标签是一个元素节点

包含在XML元素中的文本是文本节点

每一个XML属性是一个属性节点

 

SAXDOMPULL的比较

从内存占用率来说:

SAXPULLDOM占用的更少的内存解析方式,更加适合Android 手机开发。

代码:

<span style="font-size:14px;">package com.nsz.domparser;

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

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

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

public class DomService {
	
	public List<Person> getPersons(InputStream inputStream) throws Exception{
		List<Person> list = new ArrayList<Person>();
		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dbf.newDocumentBuilder();
		Document document = builder.parse(inputStream);
		Element element = document.getDocumentElement();
		
		NodeList personNodes = element.getElementsByTagName("person");
		for(int i=0; i<personNodes.getLength(); i++){
			Element personElement = (Element) personNodes.item(i);
			Person p = new Person();
			
			p.setId(Integer.parseInt(personElement.getAttribute("id")));
			NodeList childNodes = personElement.getChildNodes();
			System.out.println("*****"+childNodes.getLength());
			
			for (int j = 0; j < childNodes.getLength(); j++) {
				if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
					if ("name".equals(childNodes.item(j).getNodeName())) {
						p.setName(childNodes.item(j).getFirstChild()
								.getNodeValue());
					} else if ("age".equals(childNodes.item(j).getNodeName())) {
						p.setAge(Integer.parseInt(childNodes.item(j)
								.getFirstChild().getNodeValue()));
					}
				}
			}
			list.add(p);
		}
		
		return list;
	}
}
测试
package com.nsz.domparser;

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

public class Test {

	public static void main(String[] args) throws Exception {
		String path = "http://localhost:8080/test/person.xml";
		InputStream input = HttpUtils.getXML(path);
		DomService dom = new DomService();
		List<Person> persons = dom.getPersons(input);
		for (Person p : persons) {
			System.out.println(p.toString());
		}
	}
}
</span>

code下载地址:http://download.csdn.net/download/u012301841/7812061
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值