Android解析XML三种方式
2015-11-25 15:52
363 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011247160/article/details/50038275
三种方式分别为SAX、PULL和DOM
先准备封装数据的类与http工具类
package com.lee.testxml1116.bean; /** * 存储person数据的bean类 * @author Lee * */ public class Person { private int id; private int age; private String name; public Person() { // TODO Auto-generated constructor stub } public Person(int id, int age, String name) { super(); this.id = id; this.age = age; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [id=" + id + ", age=" + age + ", name=" + name + "]"; } }
package com.lee.testxml1116.utils; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class HttpUtil { public HttpUtil() { // TODO Auto-generated constructor stub } /** * 获取http输入字节流,通过流获取服务器端返回的数据 * @param path * @return */ public static InputStream getXML(String path){ InputStream is = null; try { URL url = new URL(path); if(null != url){ // 创建http连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置连接超时时间为3秒 connection.setConnectTimeout(3000); connection.setDoInput(true); // 设置请求方式为get connection.setRequestMethod("GET"); // 获取服务器响应状态码 int code = connection.getResponseCode(); // 若状态码为200(即正常),获取输入流 if(200 == code) is = connection.getInputStream(); } } catch (Exception e) { // TODO: handle exception } return is; } }
一、SAX方式
用到org.xml.sax.helpers.DefaultHandler,所以要定义自己的handler类,重写读取xml文件的相关方法
package com.lee.testxml1116.utils; 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 MySaxHandler 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 MySaxHandler(String nodeName) { super(); // TODO Auto-generated constructor stub 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 { // 判断当前元素(节点)是否为要解析的根元素(节点),如果是,则创建存储解析对象信息的map System.out.println(qName); if(nodeName.equals(qName)){ map = new HashMap<String, String>(); } System.out.println(map); // 判断该元素是否有标签内属性,有则存入map if(!(null == attributes || null == map)){ for(int i = 0;i < attributes.getLength();i++){ System.out.println(attributes.getQName(i)); map.put(attributes.getQName(i), attributes.getValue(i)); } } currentTag = qName; } /** * 读到元素(节点)中字符类型数据时调用的方法 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // 判断当前元素(节点)名称是否为空,不为空,则取值 if(!(null == map || null == currentTag)){ currentValue = new String(ch, start, length); // 判断当前值是否为空、是否等于换行符,两者均否,则存入map if(!(null == currentValue || "".equals(currentValue.trim()) || "\n".equals(currentValue.trim()))){ map.put(currentTag, currentValue); } } // 存储数据结束后,将currentTag与currentValue初始化 currentTag = null; currentValue = null; } /** * 读到元素(节点)结束标记时调用的方法 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { // 判断当前结束标记是否为目标根节点,若是,则将map存入list中 if(qName.equals(nodeName)){ list.add(map); // 将map初始化 map = null; } } /** * 读到文档结束时调用的方法 */ @Override public void endDocument() throws SAXException { // } }
定义完handler之后,创建一个service类,来封装从xml中获取数据的方法
package com.lee.testxml1116.service; import java.io.InputStream; import java.util.HashMap; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import com.lee.testxml1116.utils.MySaxHandler; /** * 以SAX方式解析xml并返回数据的服务类 * @author Lee * */ public class SaxService { public SaxService() { // TODO Auto-generated constructor stub } public static List<HashMap<String,String>> readXML(InputStream is, String nodeName){ try { // 创建SAX解析工厂,获取一个解析对象 SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); // 创建一个自定义DefaultHandler对象 MySaxHandler handler = new MySaxHandler(nodeName); // 解析xml parser.parse(is, handler); // 关闭InputStream if(null != is) is.close(); // 返回存储数据的list集合 return handler.getList(); } catch (Exception e) { // TODO: handle exception } return null; } }
二、Pull方式
当使用pull方式解析xml时,需要用到第三方包kxml,这里使用的是kxml2-2.2.2.jar
主要用到的类就是org.xmlpull.v1.XmlPullParser
package com.lee.testxml1116.utils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import com.lee.testxml1116.bean.Person; /** * 以pull方式解析xml的工具类 * @author Lee * */ public class PullXMLUtil { public PullXMLUtil() { // TODO Auto-generated constructor stub } public static List<Person> parseXML(InputStream is, String encode) throws XmlPullParserException, NumberFormatException, IOException{ List<Person> persons = null; Person person = null; XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser(); parser.setInput(is, encode); int eventType = parser.getEventType(); while(eventType != XmlPullParser.END_DOCUMENT){ switch (eventType) { case XmlPullParser.START_DOCUMENT: persons = 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("age".equals(parser.getName())){ int age = Integer.parseInt(parser.nextText()); person.setAge(age); } else if("name".equals(parser.getName())){ String name = parser.nextText(); person.setName(name); } break; case XmlPullParser.END_TAG: if("person".equals(parser.getName())){ persons.add(person); person = null; } break; } eventType = parser.next(); } return persons; } }
三、DOM方式
package com.lee.testxml1116.utils; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.soap.Node; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.lee.testxml1116.bean.Person; /** * 以DOM方式解析xml的工具类 * * @author Lee * */ public class DomXMLUtil { public DomXMLUtil() { // TODO Auto-generated constructor stub } /** * 从在http连接中取到的流中读取xml数据 * * @param is * @return * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ public static List<Person> readXML(InputStream is) throws ParserConfigurationException, SAXException, IOException { List<Person> persons = new ArrayList<Person>(); // 创建一个文档构造器工厂,用以获取文档构造器 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 获取一个文档构造器的实例,用以获取文档 DocumentBuilder builder = dbf.newDocumentBuilder(); // 获取一个文档实例 Document document = builder.parse(is); // 获取文档中的元素集合 Element element = document.getDocumentElement(); // 在元素集合中获取目标节点的集合 NodeList personNodes = element.getElementsByTagName("person"); // 遍历目标节点集合,解析xml for (int i = 0; i < personNodes.getLength(); i++) { // 获取当前的目标节点 Element personElement = (Element) personNodes.item(i); Person person = new Person(); // 获取当前节点中属性的值,并给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){ String nodeName = childNodes.item(j).getNodeName(); String nodeValue = childNodes.item(j).getFirstChild().getNodeValue(); if("name".equals(nodeName)){ person.setName(nodeValue); } else if("age".equals(nodeName)){ person.setAge(Integer.parseInt(nodeValue)); } } } // 子节点集合遍历结束后,即已经完成对一个person节点的解析,因此将一个完整的person对象存入list中 persons.add(person); } return persons; } }
最后附上测试类,对这三种方式进行测试
package com.lee.testxml1116.test; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import org.xmlpull.v1.XmlPullParserException; import com.lee.testxml1116.bean.Person; import com.lee.testxml1116.utils.DomXMLUtil; import com.lee.testxml1116.utils.HttpUtil; import com.lee.testxml1116.utils.PullXMLUtil; /** * 测试类 * @author Lee * */ public class Test { public Test() { // TODO Auto-generated constructor stub } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String path = "目标xml文件的url地址"; InputStream is = HttpUtil.getXML(path); /* * 以SAX方式解析 List<HashMap<String,String>> list = SaxService.readXML(is, "person"); for(HashMap<String, String> map : list){ System.out.println(map.toString()); } */ List<Person> persons = null; /* * 以pull方式解析 try { persons = PullXMLUtil.parseXML(is, "UTF-8"); for(Person person : persons){ System.out.println(person.toString()); } } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } */ // 以dom方式解析 try { persons = DomXMLUtil.readXML(is); for(Person person : persons){ System.out.println(person.toString()); } } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
三种方法相比,由于dom使用的是循环嵌套,所以当xml节点层级较多时,效率会比前两者略低。
相关文章推荐
- Android中三种解析xml方式
- 详解android解析Xml的三种方式——DOM、SAX以及XMLpull
- AndroidXml解析的三种方式list的转换
- Android中xml 解析三种方式的区别
- Android XML 三种解析方式
- android解析XML总结(SAX、Pull、Dom三种方式)
- android解析XML总结(SAX、Pull、Dom三种方式)
- 详解android解析Xml的三种方式——DOM、SAX以及XMLpull
- android解析XML总结(SAX、Pull、Dom三种方式)
- Android解析XML的三种方式SAX、Pull、Dom
- 本文介绍在Android平台中实现对XML的三种解析方式。
- Android中XML的三种解析方式
- 详解android解析Xml的三种方式——DOM、SAX以及XMLpull
- android解析XML总结(SAX、Pull、Dom三种方式)
- Android实现XML解析的三种方式
- Android平台中实现对XML的三种解析方式(DOM 、PULL、 SAX)
- Android解析XML三种方式(PULL、SAX、DOM)
- Android中解析XML的三种方式
- android解析XML总结(SAX、Pull、Dom三种方式)
- android解析XML总结(SAX、Pull、Dom三种方式)