Android解析XML三种方式
来源:互联网 发布:mac下win 10安装重启 编辑:程序博客网 时间:2024/04/29 20:32
三种方式分别为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节点层级较多时,效率会比前两者略低。
0 0
- android XML三种解析方式
- Android解析XML的三种方式
- Android中的三种XML解析方式
- Android中的三种XML解析方式
- android 解析xml的三种方式
- Android三种解析XML方式
- android 三种xml解析方式
- Android三种方式解析Xml
- Android XML 三种解析方式
- Android 解析xml的三种方式
- Android解析XML三种方式
- Android中的三种XML解析方式
- Android三种主要解析XML方式
- Android解析XML的三种方式
- Android 三种方式解析XML
- Android:解析XML的三种方式
- Android解析XML三种方式
- Android解析XML的三种方式
- Segment Sieve
- 插入到sql中的数据包含单引号(')的处理方法
- setTranslationY()
- scala io操作
- 基本数据类型之字符串
- Android解析XML三种方式
- mysql增加新用户和无法登陆解决方法
- 网页设计大赛第八天
- 单词~o(^▽^)o
- andriod 技术点总结
- 【运营推广】APP运营推广超级攻略(2015新版)
- 黑马程序员—— 高新技术---反射
- 【笔记】CSS3transform属性
- iOS 上下有黑边问题解决