在我的另一篇文章(http://www.cnblogs.com/anivia/p/5849712.html)中,通过一个例子介绍了使用DOM来解析XML文件,那么本篇文章通过相同的XML文件介绍如何使用SAX来解析XML文件,就不多说介绍了,还是只介绍如何使用和使用流程,具体其他的细节属性等,朋友们可以查阅文档,在学习工作中慢慢积累!
XML文件还是上次那个:
<?xml version="1.0" encoding="UTF-8"?> <Root> <Book> <name>偷影子的人</name> <author>马克李维</author> <year>2010</year> </Book> <Book> <name>人生不设限</name> <author>尼克胡哲</author> <year>2010</year> </Book> </Root>
这次使用SAX解析XML文件的JAVA代码:
package com.minlz.xml; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * @author minliangzhi * @date 2016年9月7日 * SIMPLE API FOR XML * SAX是一种基于流的解析方法,通过逐行扫描文档并解析,可以不必一次性加载大型文档进入内存(优势所在) */ public class SaxParser { public static void main(String[] args) { /** * 使用SAX解析XML和使用DOM的方法大致相同,也是通过工厂模式获取相应的解析器 * 构建解析工厂,构建解析器,进行解析文档,不同的是,SAX需要提供一个解析过程中的Handler, * 我们需要实现相应的方法,来完成文档的解析工作 */ SAXParserFactory facotry = SAXParserFactory.newInstance(); try { SAXParser parser = facotry.newSAXParser(); MySAXHandler handler = new MySAXHandler(); parser.parse("resources/books.xml", handler); Map<Integer, Map<String, Object>> entities = handler.getEntityes(); List<SaxBook> books = new ArrayList<SaxBook>(); for(Map<String, Object> map : entities.values()) { books.add(buildObject(SaxBook.class, map)); } for(SaxBook book : books) { System.out.println(book); } } catch (Exception e) { e.printStackTrace(); } } private static <T> T buildObject(Class<T> clazz, Map<String, Object> attributes) { T t = null; try { /** 初始化一个实例 */ t = clazz.newInstance(); Field[] allFields = clazz.getDeclaredFields(); /** 遍历所有属性,如果发现已经提供了属性的值,则设置该值 */ for(Field f : allFields) { if(attributes.containsKey(f.getName())) { f.setAccessible(true); f.set(t, attributes.get(f.getName())); } } } catch (Exception e) { e.printStackTrace(); } return t; } } class MySAXHandler extends DefaultHandler { /** * 存储解析出来的每个实体属性集合 */ Map<Integer, Map<String, Object>> entityes = null; /** * 已经解析的实体数目 */ private int size; /** * 正在开始解析的节点(我们只是记录了属性节点) */ private String currentTag = null; public MySAXHandler() { entityes = new HashMap<Integer, Map<String, Object>>(); } /** * 开始解析XML文件的时候调用 和endDocument()方法一样,都是被调用一次 */ @Override public void startDocument() throws SAXException { super.startDocument(); System.out.println("MySAXHandler 开始解析XML文件"); } /** * XML文件解析结束的时候调用 和startDocument()方法一样,都是被调用一次 */ @Override public void endDocument() throws SAXException { super.endDocument(); System.out.println("MySAXHandler 结束解析XML文件"); } /** * 开始解析一个元素标签的时候进行调用 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if(qName.equals("Book")) { // 实体开始节点 size ++; Map<String, Object> att = new HashMap<String, Object>(); entityes.put(size, att); } else if(!qName.equals("Root")){ // 属性节点 currentTag = qName; } } /** * 获取元素内容调用 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); if(currentTag != null) { // 开始解析一个属性节点 (根据currentTag的设置时间点,这里只会处理属性节点) String currentValue = new String(ch, start, length); if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){ entityes.get(size).put(currentTag, currentValue); } } } /** * 元素解析完成时调用 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); } public Map<Integer, Map<String, Object>> getEntityes() { return entityes; } public void setEntityes(Map<Integer, Map<String, Object>> entityes) { this.entityes = entityes; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } } class SaxBook { private String name; private String author; private String year; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } @Override public String toString() { return "Book [name=" + name + ", author=" + author + ", year=" + year + "]"; } }
解析结果:
MySAXHandler 开始解析XML文件 MySAXHandler 结束解析XML文件 Book [name=偷影子的人, author=马克李维, year=2010] Book [name=人生不设限, author=尼克胡哲, year=2010]
有关于每个方法和使用规则,在代码中已经有相印的解释,朋友们可以把代码粘贴到自己的编辑器中运行跟踪查看。
最后:
如果错误,还请指正,不胜感激!