[置顶] Android开发之XML文件的解析

Android系统开发之XML文件的解析

       我们知道Http在网络传输中的数据组织方式有三种分别为:XML方式、HTML方式、JSON方式。其中XML为可扩展标记语言,如下:

 

<?xml version="1.0" encoding="UTF-8"?>

<persons>

	<person id="23">

		<name>Jack</name>

		<age>23</age>

	</person>

	<person id="20">

		<name>Tom</name>

		<age>25</age>

	</person>

</persons>


    Android中解析XML数据有三种方式:分别为 DOM、SAX、和XMLPULL。下面我们分别介绍这三种方式:

 

1)SAX(org.xml.sax) 方式

Simple API for XML,以事件的形式通知程序,对XML进行解析。SAX是一种以事件驱动的XML api,由他定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,特点是:解析速度快,占用内存少。

代码流程:
1) 定义一个类继承于DefaultHandler,重写其startDocument、startElement、endDocument、endElement、characters三个方法。

 

public class MySaxHandler extends DefaultHandler {



	private HashMap<String, String> map = null;	// 存储单个解析的完整对象

	private List<HashMap<String, String>> list = null;	// 存储所有的解析对象

	

	private String currentTag = null;	// 正在解析的元素的标签

	private String currentValues = null;	// 解析当前元素的值	

	private String nodeName = null;			// 解析当前的节点名称

	

	public MySaxHandler(String nodeName) {

		// TODO Auto-generated constructor stub

		this.nodeName = nodeName;

	}



	/**

	 * @return the list

	 */

	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++) {

				map.put(attributes.getQName(i),attributes.getValue(i));

			}

		}

		currentTag = qName;

	}

	

	@Override

	public void endDocument() throws SAXException {

		// TODO Auto-generated method stub

		super.endDocument();

	}

	

	@Override

	public void endElement(String uri, String localName, String qName)

			throws SAXException {

		// 遇到结束标记的时候调用

		if(qName.equals(nodeName)) {

			list.add(map);

			map = null;

		}

	}

	

	@Override

	public void characters(char[] ch, int start, int length)

			throws SAXException {

		// 处理XML文件所读取到的内容

		if(currentTag != null && map != null) {

			currentValues = new String(ch, start, length);

			if(currentValues != null && !currentValues.trim().equals("") && 

					!currentValues.trim().equals("\n")) {

				map.put(currentTag, currentValues);

			}

		}

		currentTag = null;	// 当前节点对应的值和标签设置为空

		currentValues = null;

	}

}


2) 定义一个处理流的类SaxService,调用SAXParserFactory创建一个SAXParser从输入流解析XML文件。

 

 

public class SaxService {



	public static List<HashMap<String, String>> readXml(

			InputStream inputStream, String nodeName) {

		try {

			// 创建一个解析XML的工厂对象

			SAXParserFactory spFactory = SAXParserFactory.newInstance();

			SAXParser parser = spFactory.newSAXParser();

			MySaxHandler handler = new MySaxHandler(nodeName);

			parser.parse(inputStream, handler);

			inputStream.close();

			return handler.getList();



		} catch (Exception e) {

			// TODO: handle exception

		}

		return null;

	}



	public SaxService() {

	}

}

 

 

3) 定义一个测试类Test,读取文件FileInputStream调用SaxService.readXml()处理。

 

public class Test {



	/**

	 * @param args

	 */

	public static void main(String[] args) {

		// TODO Auto-generated method stub

		try {

			File file = new File("C://test.xml");

			if(file.exists()) {

				FileInputStream inputStream = new FileInputStream(file);

				List<HashMap<String, String>> list = SaxService.readXml(inputStream, "person");

				for(HashMap<String, String> map : list) {

					System.out.println(map.toString());

				}

			} else {

				System.out.println("file is not exitst");

			}

			

		} catch (Exception e) {

			// TODO: handle exception

		}

	}

}

 


2)DOM方式

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

节点类型:
       整个文档是一个节点文档,每个xml标签是一个元素节点,包含在XML元素中的文本是文本节点每个XML属性是一个属性节点。

 

public class DomXml {



	public DomXml() {

		// TODO Auto-generated constructor stub

	}



	public List<Person> getPersons(InputStream inputStream) throws Exception {

		List<Person> list = new ArrayList<Person>();

		// 创建一个document解析的工厂

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		DocumentBuilder builder = factory.newDocumentBuilder();

		Document document = builder.parse(inputStream);

		Element element = document.getDocumentElement();

		NodeList personNodeList = element.getElementsByTagName("person");

		for(int i = 0; i < personNodeList.getLength(); i++) {

			Element personElement = (Element)personNodeList.item(i);

			Person person = new Person();

			person.setId(Integer.parseInt(personElement.getAttribute("id")));

			NodeList childNodes = personElement.getChildNodes();

			for(int j = 0; j < childNodes.getLength(); j++) {

				if(childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {

					if("name".equals(childNodes.item(j).getNodeName())) {

						person.setName(childNodes.item(j).getFirstChild().getNodeValue());

					} else if("age".equals(childNodes.item(j).getNodeName())) {

						person.setAge(Integer.parseInt(childNodes.item(j).getFirstChild().getNodeValue()));

					}

				}

			}

			list.add(person);

		}

		return list;

	}

	

	public static void main(String[] args) throws Exception {

		

		FileInputStream inputStream = new FileInputStream("C://test.xml");

		DomXml domXml = new DomXml();

		List<Person> list = domXml.getPersons(inputStream);

		for(Person person : list) {

			System.out.println(person.toString());

		}

	}

}

 


3)XMLPULL(org.xmlpull.v1) 方式

1) 新建一个项目,导入kxml2-2.2.2.jar包,创建一个描述信息Person类。

        kxml2-2.2.2.jar包下载地址:http://download.csdn.net/detail/llping2010/6270791

public class Person {



	private String name;

	private int age;

	private int id;

	

	

	public Person() {

		// TODO Auto-generated constructor stub

	}

	

	public Person(String name, int age, int id) {

		super();

		this.name = name;

		this.age = age;

		this.id = id;

	}



	/**

	 * @return the name

	 */

	public String getName() {

		return name;

	}



	/**

	 * @param name the name to set

	 */

	public void setName(String name) {

		this.name = name;

	}



	/**

	 * @return the age

	 */

	public int getAge() {

		return age;

	}



	/**

	 * @param age the age to set

	 */

	public void setAge(int age) {

		this.age = age;

	}



	/**

	 * @return the id

	 */

	public int getId() {

		return id;

	}



	/**

	 * @param id the id to set

	 */

	public void setId(int id) {

		this.id = id;

	}



	/* (non-Javadoc)

	 * @see java.lang.Object#toString()

	 */

	@Override

	public String toString() {

		return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";

	}

}



2) 创建一个PullXmlTools类,根据inputStream获取输入调用XmlPullParserFactoty解析XML将解析的数据保存到List<Person> list中返回。

public class PullXmlTools {

	

	public PullXmlTools() {

		// TODO Auto-generated constructor stub

	}



	public static List<Person> parseXml(InputStream inputStream, String encode) throws XmlPullParserException, IOException {

		List<Person> list = null;

		Person person = null;

		

		// 创建一个xml解析的工厂

		XmlPullParserFactory xppFactovy = XmlPullParserFactory.newInstance(); 

		// 获得xml解析类的引用

		XmlPullParser parser = xppFactovy.newPullParser();

		// 设置parser解析器的输入和编码类型

		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.getAttributeName(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.getEventType();

		}	

		return list;

	}

}



3) 定义一个测试类Test,读取文件FileInputStream调用PullXmlTools.parserXml()处理。

 

 

 

 

 

public class Test {



	/**

	 * @param args

	 */

	public static void main(String[] args) {

		// TODO Auto-generated method stub

		

		try {

			File file = new File("C://test.xml");

			if(file.exists()) {

				FileInputStream inputStream = new FileInputStream(file);

				List<Person> list = PullXmlTools.parseXml(inputStream, "utf-8");

				for(Person person : list) {

					System.out.println(person.toString());

				}

			} else {

				System.out.println("file is not exitst");

			}

			

		} catch (Exception e) {

			// TODO: handle exception

		}

	}

}

 


 

你可能感兴趣的:(Android开发)