[置顶] 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("
")) {
				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
		}
	}
}


原文地址:https://www.cnblogs.com/riskyer/p/3323018.html