Java:XML篇,使用SAX读取并解析XML数据
1. 描述
参考:http://www.cnblogs.com/duanxz/archive/2012/08/08/2628416.html,Java中用SAX解析XML,具体包括读写,这篇是读取示范。
SAX(Simple API for XML) SAX 允许您在读取文档时处理它,它遍历文档并产生事件表示这一过程。 SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver,ErrorHandler。 实际上只要继承DefaultHandler类 ,再覆盖一部分 处理事件的方法
- SAX 它的解析是连续的;
- SAX 数据无法回朔。
2. 示范代码
package com.clzhang.sample.xml; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.Locator; import org.xml.sax.InputSource; import org.xml.sax.helpers.DefaultHandler; /** * 参考:http://www.cnblogs.com/duanxz/archive/2012/08/08/2628416.html * SAX(Simple API for XML) SAX 允许您在读取文档时处理它,它遍历文档并产生事件表示这一过程。 SAX * API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler, EntityResolver, * ErrorHandler。 实际上只要继承DefaultHandler类 ,再覆盖一部分 处理事件的方法 * 1.SAX 它的解析是连续的; * 2.SAX 数据无法回朔。 * @author Administrator */ class MyContentHandler extends DefaultHandler { StringBuffer jsonStringBuffer; int frontBlankCount = 0; public MyContentHandler() { jsonStringBuffer = new StringBuffer(); } /* * 接收用来查找 SAX 文档事件起源的对象。 * @param locator 可以返回任何 SAX文档事件位置的对象 */ @Override public void setDocumentLocator(Locator locator) { System.out.println(this.toBlankString(this.frontBlankCount) + ">>> set document_locator : (lineNumber = " + locator.getLineNumber() + ",columnNumber = " + locator.getColumnNumber() + ",systemId = " + locator.getSystemId() + ",publicId = " + locator.getPublicId() + ")"); } /* * 接收文档的开始的通知。 */ @Override public void startDocument() throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount++) + ">>> start document "); } /* * 接收文档的结尾的通知。 */ @Override public void endDocument() throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount) + ">>> end document"); } /* * 接收元素开始的通知。 * @param uri 元素的命名空间 * @param localName 元素的本地名称(不带前缀) * @param qName 元素的限定名(带前缀) * @param atts 元素的属性集合 */ @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount++) + ">>> start element : " + qName + "(" + uri + ")"); } /* * 接收文档的结尾的通知。 * @param uri 元素的命名空间 * @param localName 元素的本地名称(不带前缀) * @param qName 元素的限定名(带前缀) */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount) + ">>> end element : " + qName + "(" + uri + ")"); } /* * 开始前缀 URI 名称空间范围映射。 此事件的信息对于常规的命名空间处理并非必需: 当 * http://xml.org/sax/features/namespaces 功能为 true(默认)时, SAX XML读取器 * 将自动替换元素和属性名称的前缀。 * @param prefix 前缀 * @param uri 命名空间 */ @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount++) + ">>> start prefix_mapping : xmlns:" + prefix + " = " + "\"" + uri + "\""); } /* * 结束前缀 URI 范围的映射。 */ @Override public void endPrefixMapping(String prefix) throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount) + ">>> end prefix_mapping : " + prefix); } /* * 接收元素内容中可忽略的空白的通知。 参数意义如下: * @param ch 来自 XML 文档的字符 * @param begin 数组中的开始位置 * @param length 从数组中读取的字符的个数 */ @Override public void ignorableWhitespace(char[] ch, int begin, int length) throws SAXException { StringBuffer buffer = new StringBuffer(); for (int i = begin; i < begin + length; i++) { switch (ch[i]) { case '\\': buffer.append("\\\\"); break; case '\r': buffer.append("\\r"); break; case '\n': buffer.append("\\n"); break; case '\t': buffer.append("\\t"); break; case '\"': buffer.append("\\\""); break; default: buffer.append(ch[i]); } } System.out.println(this.toBlankString(this.frontBlankCount) + ">>> ignorable whitespace(" + length + "): " + buffer.toString()); } /* * 接收处理指令的通知。 参数意义如下: * @param target 处理指令目标 * @param data 处理指令数据,如果未提供,则为 null。 */ @Override public void processingInstruction(String target, String data) throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount) + ">>> process instruction : (target = \"" + target + "\",data = \"" + data + "\")"); } /* * 接收跳过的实体的通知。 * @param name 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头; * 如果它是外部 DTD 子集,则将是字符串"[dtd]" */ @Override public void skippedEntity(String name) throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount) + ">>> skipped_entity : " + name); } /* * 接收字符数据的通知。 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue) */ @Override public void characters(char[] ch, int begin, int length) throws SAXException { StringBuffer buffer = new StringBuffer(); for (int i = begin; i < begin + length; i++) { switch (ch[i]) { case '\\': buffer.append("\\\\"); break; case '\r': buffer.append("\\r"); break; case '\n': buffer.append("\\n"); break; case '\t': buffer.append("\\t"); break; case '\"': buffer.append("\\\""); break; default: buffer.append(ch[i]); } } System.out.println(this.toBlankString(this.frontBlankCount) + ">>> characters(" + length + "): " + buffer.toString()); } // 缩进控制 private String toBlankString(int count) { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < count; i++) buffer.append(" "); return buffer.toString(); } } public class SAXReadTest { public static void main(String args[]) throws Exception { long lasting = System.currentTimeMillis(); SAXParserFactory sf = SAXParserFactory.newInstance(); SAXParser sp = sf.newSAXParser(); MyContentHandler ins = new MyContentHandler(); sp.parse(new InputSource("bbs.xml"), ins); System.out.println("运行时间:" + (System.currentTimeMillis() - lasting) + " 毫秒"); } }