SAX解析:适合大型的XML文件的解析
SAX解析器从上向下读,读一行处理一行,内存只存一行,不能在回读,SAX只适合读,不适合对节点的crud操作
SAX是事件处理模式解析xml,有事件处理器。SAX解析解析器每解析xml的一个组成部分,都会调用事件处理器的方法,并将解析到的xml组成部分以参数的形式传递给该方法
事件处理器有我们自己编写。
SAX内置在jdk里org.xml.sax包
实现ContentHandler接口,就相当于一个xml文档本身内容事件处理器,就是所有XML
的内容,包括元素属性。。ContentHandler接口有很多方法,解析到xml不同组成部分时的方法, startDocument() startElement() charactors() endDocument() endElement()每解析一个组成时就会调用方法,并且是按照调用顺序,一个紧挨着一个!!对一个xml文档会对每个标签迭代的按顺序执行执行startElement() charactors() endDocument(),三个方法,顺序一个接一个执行!
这里要注意charactors()方法:111代表空格空白字符(回车符换行符),每到一个空白字符都会调用charactors()方法,如下有三个空白字符,调用三次charactors()方法
<book>①1111111111
①11111<书名>wewef</书名>②1111111111
②11111<作者>wewef</作者>③1111111111
</book>
ContentHandler接口有默认实现类DefaultHandler,不用去实现所有方法!
jdk里javax.xml.parsers包下:有SAXParseFactory
1//获取xml所有内容
class SAXTest(){
main(){
1创建解析工厂
SAXParseFactory factory=SAXParceFactory.newInstance();
2获得解析器
SAXParser parse=factory.newSAXParser();
3获得读取器,读取xml
XMLReader reader=parse.getXMLReader();
4在指定文档内容钱一定先设置事件处理器,不然一旦指定文档,就马上开始读了,读的时候需要触发事件处理器
parse.setContentHandler(new MyHandler());
5指定xml文档,一旦指定文档,就读取器就马上开始读了
parser.parse(new File(xml路径)); 注册事件监听器,自己实现
}}
事件处理器定义
class MyHandler extends DefaultHandler{
//因为我们想把所有元素解析,需要个集合存放解析数据,所有元素名,
private Stack<String> stack=new Stack<String>();
private String name; private String gender; private String age;
//文档开始时会调用
@Override
startDocument(){}
//文档结束时会调用
@Override
endDocument(){}
//开始一个元素节点时会调用,元素名qName,该元素属性集合attributes会自动传入方法参数,Attributes本身是个集合
@Override
startElement(String url, String localName,String qName ,Attributes attributes){
//qName是传入的属性名
stack.push(qName);
//获取该节点的元素,不是遍历属性集合而是遍历其方法,但有可能没有属性attributes=null,会报
for(i=0; attributes !=null&i< attributes.getLength();i++){
String attrName= attributes.getQName(i) 获得属性名
String attrValue= attributes.getValue(i);
}
}
//结束一个元素时会调用,元素结束过后就取出
@Override
endElement(String url, String localName,String qName){
stack.pop();
}
//遇到文本节点(包括空白符),参数刚好是用来生成该文本String的参数!
@Override
charactors(char[]ch,int start,int legnth){
/读出包含该文本的元素节点
String tag=stack.peek();
if(“aaa”.euqals(tag)){name=new String (ch, start, legnth);} 获得文本的String形式
}}
2//获取xml指定内容,指定元素
只需改事件处理器
class MyHandler2 extends DefaultHandler{
String tagName;
public MyHandler2(String tagName){
this. tagName= tagName;
}
Attributes本身是个集合
@Override
startElement(String url, String localName,String qName ,Attributes attributes){
//如果是指定元素
if(qName.equals(tagName)){
print(qName);
for(i=0; attributes !=null&i< attributes.getLength();i++){
String attrName= attributes.getQName(i) 获得属性名
String attrValue= attributes.getValue(i);
}}
//打印完元素后,接着打印该标签文本节点,自动会转向打印该元素的文本节点
@Override
charactors(char[]ch,int start,int legnth){
print(new String (ch, start, legnth));
}
//结束一个元素时会调用,元素结束过后就取出
@Override
endElement(String url, String localName,String qName){
stack.pop();
}
}
|