packagecom.clzhang.sample.xml;importjavax.xml.parsers.SAXParser;importjavax.xml.parsers.SAXParserFactory;importorg.xml.sax.Attributes;importorg.xml.sax.SAXException;importorg.xml.sax.Locator;importorg.xml.sax.InputSource;importorg.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 数据无法回朔。
*@authorAdministrator*/
class MyContentHandler extendsDefaultHandler {
StringBuffer jsonStringBuffer;int frontBlankCount = 0;publicMyContentHandler() {
jsonStringBuffer= newStringBuffer();
}/** 接收用来查找 SAX 文档事件起源的对象。
* @param locator 可以返回任何 SAX文档事件位置的对象*/@Overridepublic voidsetDocumentLocator(Locator locator) {
System.out.println(this.toBlankString(this.frontBlankCount)+ ">>> set document_locator : (lineNumber = "
+ locator.getLineNumber() + ",columnNumber = "
+ locator.getColumnNumber() + ",systemId = "
+ locator.getSystemId() + ",publicId = "
+ locator.getPublicId() + ")");
}/** 接收文档的开始的通知。*/@Overridepublic void startDocument() throwsSAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)+ ">>> start document ");
}/** 接收文档的结尾的通知。*/@Overridepublic void endDocument() throwsSAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)+ ">>> end document");
}/** 接收元素开始的通知。
* @param uri 元素的命名空间
* @param localName 元素的本地名称(不带前缀)
* @param qName 元素的限定名(带前缀)
* @param atts 元素的属性集合*/@Overridepublic voidstartElement(String uri, String localName, String qName,
Attributes atts)throwsSAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)+ ">>> start element : " + qName + "(" + uri + ")");
}/** 接收文档的结尾的通知。
* @param uri 元素的命名空间
* @param localName 元素的本地名称(不带前缀)
* @param qName 元素的限定名(带前缀)*/@Overridepublic voidendElement(String uri, String localName, String qName)throwsSAXException {
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 命名空间*/@Overridepublic voidstartPrefixMapping(String prefix, String uri)throwsSAXException {
System.out.println(this.toBlankString(this.frontBlankCount++)+ ">>> start prefix_mapping : xmlns:" + prefix + " = " + "\""
+ uri + "\"");
}/** 结束前缀 URI 范围的映射。*/@Overridepublic void endPrefixMapping(String prefix) throwsSAXException {
System.out.println(this.toBlankString(--this.frontBlankCount)+ ">>> end prefix_mapping : " +prefix);
}/** 接收元素内容中可忽略的空白的通知。 参数意义如下:
* @param ch 来自 XML 文档的字符
* @param begin 数组中的开始位置
* @param length 从数组中读取的字符的个数*/@Overridepublic void ignorableWhitespace(char[] ch, int begin, intlength)throwsSAXException {
StringBuffer buffer= newStringBuffer();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。*/@Overridepublic voidprocessingInstruction(String target, String data)throwsSAXException {
System.out.println(this.toBlankString(this.frontBlankCount)+ ">>> process instruction : (target = \"" +target+ "\",data = \"" + data + "\")");
}/** 接收跳过的实体的通知。
* @param name 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头;
* 如果它是外部 DTD 子集,则将是字符串"[dtd]"*/@Overridepublic void skippedEntity(String name) throwsSAXException {
System.out.println(this.toBlankString(this.frontBlankCount)+ ">>> skipped_entity : " +name);
}/** 接收字符数据的通知。 在DOM中 ch[begin:end] 相当于Text节点的节点值(nodeValue)*/@Overridepublic void characters(char[] ch, int begin, intlength)throwsSAXException {
StringBuffer buffer= newStringBuffer();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(intcount) {
StringBuffer buffer= newStringBuffer();for (int i = 0; i < count; i++)
buffer.append(" ");returnbuffer.toString();
}
}public classSAXReadTest {public static void main(String args[]) throwsException {long lasting =System.currentTimeMillis();
SAXParserFactory sf=SAXParserFactory.newInstance();
SAXParser sp=sf.newSAXParser();
MyContentHandler ins= newMyContentHandler();
sp.parse(new InputSource("bbs.xml"), ins);
System.out.println("运行时间:" + (System.currentTimeMillis() -lasting)+ " 毫秒");
}
}