快速解析XML
SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,相对于DOM而言占用内存较少。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在startElement方法中,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。 SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器: 备注说明:SAX API中主要有四种处理事件的接口,它们分别是ContentHandler,DTDHandler,EntityResolver和ErrorHandler
这里使用最多的就是ContentHandler,仔细阅读API文档,了解常用方法:startElement、endElement、characters等 1.startElement方法说明 [java]
2.endElement方法说明
voidendElement(Stringuri,StringqName) throwsSAXException接收元素结束的通知。 SAX解析器会在XML文档中每个元素的末尾调用此方法;对于每个endElement事件都将有相应的startElement事件(即使该元素为空时)。 参数: uri-名称空间URI,如果元素没有名称空间URI,或者未执行名称空间处理,则为空字符串 localName-本地名称(不带前缀),如果未执行名称空间处理,则为空字符串 qName-限定的XML名称(带前缀),如果限定名不可用,则为空字符串 voidcharacters(char[]ch,intstart,intlength) throwsSAXException 接收字符数据的通知,可以通过newString(ch,start,length)构造器,创建解析出来的字符串文本. 参数: ch-来自XML文档的字符 start-数组中的开始位置 length-从数组中读取的字符的个数 说明:xml中每个标签的文本内容是在characters方法里处理的。 比如在如下:
在<西游记 id="x001"><作者>吴承恩</作者></西游记>里 吴承恩这个文本就是在characters方法里处理的。 其中<西游记></西游记>和<作者></作者>是标签(qname) id="x001"是属性(atts)和值 其它方法请参考api数据
下面我们就具体讲解sax解析的操作. 一.我们通过XMLReaderFactory、XMLReader完成,步骤如下1.通过XMLReaderFactory创建XMLReader对象 XMLReaderreader=XMLReaderFactory.createXMLReader(); 2.设置事件处理器对象 reader.setContentHandler(newMyDefaultHandler()); 3.读取要解析的xml文件 FileReaderfileReader=newFileReader(newFile("srcsaxstartelementweb.xml")); 4.指定解析的xml文件 reader.parse(newInputSource(fileReader)); 案例:通过案例对uri、localName、qName和attribute参数有更加深入的了解 1.首先创建要解析的web.xml文件,内容如下 [html]
2.创建解析测试类及事件处理的内部类代码如下 packagesax.startelement; importjava.io.File; importjava.io.FileReader; importorg.junit.Test; importorg.xml.sax.Attributes; importorg.xml.sax.InputSource; importorg.xml.sax.SAXException; importorg.xml.sax.XMLReader; importorg.xml.sax.helpers.DefaultHandler; importorg.xml.sax.helpers.XMLReaderFactory; publicclassDemo3{ @Test publicvoidtest()throwsException{ //通过XMLReaderFactory创建XMLReader对象 XMLReaderreader=XMLReaderFactory.createXMLReader(); //设置事件处理器对象 reader.setContentHandler(newMyDefaultHandler()); //读取要解析的xml文件 FileReaderfileReader=newFileReader(newFile( "srcsaxstartelementweb.xml")); //指定解析的xml文件 reader.parse(newInputSource(fileReader)); } //自定义的解析类,通过此类中的startElement了解uri,localName,qName,Attributes的含义 classMyDefaultHandlerextendsDefaultHandler{ @Override publicvoidstartElement(Stringuri,Attributesattributes)throwsSAXException{ super.startElement(uri,attributes); System.out .println("--------------startElement开始执行--------------------------"); System.out.println("uri:::"+uri); System.out.println("localName:::"+localName); System.out.println("qName:::"+qName); for(inti=0;i<attributes.getLength();i++){ Stringvalue=attributes.getValue(i);//获取属性的value值 System.out.println(attributes.getQName(i)+"-----"+value); } System.out.println("------------------startElement执行完毕---------------------------"); } } } 3.程序运行的结果如下:
通过运行结果,希望你对uri,qName有更加深入的了解. 二.我们通过SAXParserFactory、SAXParser完成,步骤如下(建议使用)说明:如果只是使用SAXParserFactory、SAXParser他们完成只需要如下3步骤 1.获取sax解析器的工厂对象 案例:解析出"作者"元素标签中的文本内容 1.需要解析的sida.xml文件 2.解析测试类和事件处理器类的实现代码 packagesax; importjava.io.File; importjavax.xml.parsers.SAXParser; importjavax.xml.parsers.SAXParserFactory; importorg.junit.Test; importorg.xml.sax.Attributes; importorg.xml.sax.SAXException; importorg.xml.sax.helpers.DefaultHandler; publicclassSaxTest{ @Test publicvoidtest()throwsException{ //1.获取sax解析器的工厂对象 SAXParserFactoryfactory=SAXParserFactory.newInstance(); //2.通过工厂对象SAXParser创建解析器对象 SAXParsersaxParser=factory.newSAXParser(); //3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象 saxParser.parse(newFile("src//sax//sida.xml"),newMyDefaultHandler()); } //自己定义的事件处理器 classMyDefaultHandlerextendsDefaultHandler{ //解析标签开始及结束的的标识符 booleanisOk=false; @Override publicvoidstartElement(Stringuri,attributes); //当解析作者元素开始的时候,设置isOK为true if("作者".equals(qName)){ isOk=true; } } @Override publicvoidcharacters(char[]ch,intlength) throwsSAXException{ //TODOAuto-generatedmethodstub super.characters(ch,length); //当解析的标识符为true时,打印元素的内容 if(isOk){ System.out.println(newString(ch,length)); } } @Override publicvoidendElement(Stringuri,StringqName) throwsSAXException{ super.endElement(uri,qName); //当解析作者元素的结束的时候,设置isOK为false if("作者".equals(qName)){ isOk=false; } } } } 3.程序运行结果如下: 原文地址:http://blog.csdn.net/redarmy_chen/article/details/12951649 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |