这篇博文介绍XML数据的解析,接上一篇博文:关于园子客户端实现的研究一
大家都知道实现XML文件解析有三种方式:DOM,SAX,PULL
为了实现学习的目的,都实现一遍,就是这么任性
》创建实体类
public class Blog { private String blogId; // id private String title; // 标题 private String published; // 发表时间 private String updated; // 更新时间 private String urlPath; // 文章路径 private String diggs; // 推荐数 private String views; // 阅读数 private String comments; // 评论数 private Author author;//作者 ... }
public class Author { private String name; //姓名 private String uri; //网址 private String avatar; //头像 ... }
有了实体就可以开始解析了
1、DOM方式
原理:解析器读入整个文档,将文件分为独立的元素、属性和注释等,然后构造一个驻留内存的树结构,通过节点树访问文档的内容;
优点:DOM在内存中以树形结构存放,因此检索和更新效率会更高。
缺点:对于特别大的文档,解析和加载整个文档将会很耗资源。
public class DomParser { public static List<Blog> getBlogs(InputStream is) throws Exception { List<Blog> blogs = new ArrayList<Blog>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 创建DON解析器 DocumentBuilder dombuild = factory.newDocumentBuilder(); // 开始解析XML文档并且得到整个文档的对象模型 Document dom = dombuild.parse(is); // 得到根节点 Element root = dom.getDocumentElement(); // 遍历根节点下所有的子节点 NodeList nodeList = root.getElementsByTagName("entry"); for (int i = 0; i < nodeList.getLength(); i++) { Blog blog = new Blog(); Element element = (Element) nodeList.item(i); Element id = (Element) element.getElementsByTagName("id").item(0); blog.setBlogId(id.getFirstChild().getNodeValue()); Element title = (Element) element.getElementsByTagName("title").item(0); blog.setTitle(title.getFirstChild().getNodeValue()); Element author = (Element) element.getElementsByTagName("author").item(0); Element name = (Element) author.getElementsByTagName("name").item(0); Author auth = new Author(); auth.setName(name.getFirstChild().getNodeValue()); blog.setAuthor(auth); Element link = (Element) element.getElementsByTagName("link").item(0); blog.setUrlPath(link.getAttribute("href")); blogs.add(blog); } return blogs; } }
2、SAX方式
原理:简单地说就是对文档进行顺序扫描
优点:SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。
缺点:不知道
public class SaxParser extends DefaultHandler { private List<Blog> blogs = null; private Blog blog = null; private Author author = null; private String preTag = null;// 作用是记录解析时的上一个节点名称 public static List<Blog> getBlogs(InputStream xmlStream) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance();// 创建SAX解析工厂 // 创建SAX解析器 SAXParser parser = factory.newSAXParser(); SaxParser handler = new SaxParser(); // 开始解析 parser.parse(xmlStream, handler); // 关闭输入流 xmlStream.close(); return handler.getBlogs(); } public List<Blog> getBlogs() { return blogs; } // 遇到文档开始标记的时候的操作 @Override public void startDocument() throws SAXException { blogs = new ArrayList<Blog>(); } // 遇到元素节点开始时候的操作 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("entry".equals(qName)) { blog = new Blog(); } else if ("author".equals(qName)) { author = new Author(); } else if ("link".equals(qName)) { if (blog != null) { blog.setUrlPath(attributes.getValue(1)); } } preTag = qName;// 将正在解析的节点名称赋给preTag } // 遇到文本节点时的操作 @Override public void characters(char[] ch, int start, int length) throws SAXException { if (preTag != null) { String content = new String(ch, start, length); if ("id".equals(preTag)) { if (blog != null) { blog.setBlogId(content); } } else if (("title").equals(preTag)) { if (blog != null) { blog.setTitle(content); } } else if ("name".equals(preTag)) { if (author != null) { author.setName(content); } } } } // 遇到元素节点结束时候的操作 @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("entry".equals(qName)) { blogs.add(blog); blog = null; } else if ("author".equals(qName)) { blog.setAuthor(author); author = null; } preTag = null; } @Override public void endDocument() throws SAXException { super.endDocument(); } }
3、PULL方式
原理:PULL解析器的运行方式和SAX类似,都是基于事件的模式。
优点:PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术。
缺点:不知道
public class PullParser { public static List<Blog> getBlogs(InputStream is) throws Exception { List<Blog> blogs = null; Blog blog = null; Author author = null; //得到Pull解析器 XmlPullParser parser = Xml.newPullParser(); //设置输入流的编码 parser.setInput(is, "UTF-8"); //得到第一个事件类型 int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT://如果是文档开始事件 blogs = new ArrayList<Blog>(); break; case XmlPullParser.START_TAG:// 如果遇到标签开始 String sName = parser.getName();// 获得解析器当前元素的名称 if ("entry".equals(sName)) { blog = new Blog(); } else if ("author".equals(sName)) { author = new Author(); } else if ("link".equals(sName)) { if (blog != null) { blog.setUrlPath(parser.getAttributeValue(1)); } } else if ("id".equals(sName)) { if (blog != null) { blog.setBlogId(new String(parser.nextText())); } } else if (("title").equals(sName)) { if (blog != null) { blog.setTitle(new String(parser.nextText())); } } else if ("name".equals(sName)) { if (author != null) { author.setName(new String(parser.nextText())); } } break; case XmlPullParser.END_TAG:// 如果遇到标签结束 String eName = parser.getName();// 获得解析器当前元素的名称 if ("entry".equals(eName)) { blogs.add(blog); blog = null; } else if ("author".equals(eName)) { blog.setAuthor(author); author = null; } break; } eventType = parser.next();//进入下一个事件处理 } return blogs; } }
4、解析完之后就是展示数据了
listview + adapter组合,这不是个事
===========================================
成功展示,接下来就是修修改改的事了,构思一下界面的设计
时间: 2024-11-04 03:20:45