加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

SAX方式解析XML文件的方法分析

发布时间:2020-12-16 05:59:07 所属栏目:百科 来源:网络整理
导读:SAX(Simple API for XML) SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理方法,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束

SAX(Simple API for XML)SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理方法,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。SAX解析方式适用于大型文档,因为他的解析是逐行进行不用像DOM中那样为所有节点创建对象,这样效率大大提高,所以虽然它不是W3C标准,但它却得到了广泛认可。

这是一个需要解析的XML文件:

<?xmlversion="1.0"encoding="utf-8"?>
<bookstore>
	<bookid="2"type="长篇小说">
			<name>《平凡的世界》</name>
			<author>路遥</author>
			<year>2014</year>
			<price>22</price>
			<outline>《平凡的世界》是中国作家路遥创作的一部百万字的小说。
			</outline>>
	</book>
	<bookid="7"type="外文小说">
		<name>"GonewiththeWind"</name>
		<author>Margaret.Mitchell</author>
		<price>99</price>
		<language>English</language>
		<outline>《飘》是美国女作家玛格丽特?米切尔(1900―1949)十年磨一剑的作品,也是惟一的作品。</outline>
	</book>
		<bookid="13"type="中文小说">
		<name>《秦腔》</name>
		<author>贾平凹</author>
		<price>99</price>
		<language>汉语</language>
		<outline>《秦腔》以两条线展开,一条线是秦腔戏曲,一条线是农民与土地的关系。</outline>>
	</book>

</bookstore>

如上所示,我们将从首行开始逐一进行解析,SAX解析时会识别开始标签和结束标签,这些用相应的方法进行实现,具体如下:

需要注意的是DefaultHandler类是SAX2事件处理程序的默认基类。它实现了EntityResolver、DTDHandler、ContentHandler和ErrorHandler这四个接口。包含这四个接口的所有方法,所以我们在编写事件处理程序时,可以不用直接实现这四个接口,而继承该类,然后重写我们需要的方法即可

我们SAX方法解析XML文件时需要一个Handler类来提供解析的方法,里面包含了重写的继承于DefaultHandler类的两种方法,分别有开始和结束的方法

packageHandler;

importjava.util.ArrayList;
importorg.xml.sax.Attributes;
importorg.xml.sax.SAXException;
importorg.xml.sax.helpers.DefaultHandler;
importentity.Book;

publicclassSAXParserHandlerBookextendsDefaultHandler{
	
	intbookIndex=0;

	Bookbook=null;
	
	privateArrayList<Book>bookList=newArrayList<Book>();
	
	publicArrayList<Book>getBookList(){
		returnbookList;
		
	}
	//用来标识解析开始和结束
	@Override
	publicvoidstartDocument()throwsSAXException{
		
		super.startDocument();
		
		System.out.println("SAX解析开始");
	}
	@Override
	publicvoidendDocument()throwsSAXException{
		
		super.startDocument();
		
		System.out.println("SAX解析开始");
	}
	
	//用来遍历XML文件的开始标签
	@Override
	publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)throwsSAXException{
	
		super.startElement(uri,localName,qName,attributes);
		//开始解析book节点的属性
		
		//注意:这种方法是知道节点名为book且其属性只有id一个属性,只需获取其属性值的情况
		if(qName.equals("book")){
			//在清空之前保存
			bookList.add(book);
			//保证每次运行到这里的时候book都是null以便保存其他子节点的值
			book=null;
			//创建book对象
			book=newBook();
			//这边我们需要一个全局变量来记录遍历进行到哪本书
			bookIndex++;
			
//			Stringvalue=attributes.getValue("id");
//【注意这种方法是知道了属性的属性名来获取属性值的简便方法】
//			System.out.println("book的属性值:"+attributes.getValue("id"));

			//在不知道book节点的属性数量以及属性名和属性值的情况下进行解析
			intlen=attributes.getLength();
			
			System.out.println("*************************开始遍历第"+(bookIndex)+"本书*************************");
			
			for(inti=0;i<len;i++){
				
				System.out.println("第"+(i+1)+"个属性:");
	
				System.out.println("属性名是:"+attributes.getQName(i));
				
				System.out.println("属性值是:"+attributes.getValue(i));				
				System.out.println();
				
				if(attributes.getQName(i).equals("id")){
				
					book.setId(attributes.getQName(i));
					
				}elseif(attributes.getQName(i).equals("type")){
				
					book.setId(attributes.getQName(i));
				}
			}
		}
		
		//获取book节点的所有子节点节点名
		if(qName!="book"){
		
			System.out.println("节点名:"+qName);	
				
		}elseif(qName.equals("author")){
		
			book.setAuthor(value);
			
		}elseif(qName.equals("year")){
		
			book.setYear(value);
			
		}elseif(qName.equals("lauguage")){
		
			book.setLauguage(value);
			
		}elseif(qName.equals("price")){
		
			book.setPrice(value);
			
		}elseif(qName.equals("outline")){
		
			book.setOutline(value);
			
		}elseif(qName.equals("name")){
		
			book.setName(value);
		}
	}
	//以上部分用switch语句实现代码开起来应该会相对整洁一点,
	Stringvalue=null;
	
	@Override
	publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXException{
		
		super.characters(ch,start,length);
		
		value=newString(ch,length);
		
		if(!value.trim().equals("")){	
			
			System.out.println("节点值:"+value);
			
			System.out.println();
		}
	}
	
	
	//用来遍历XML结束标签(non-Javadoc)
	@seeorg.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,java.lang.String,java.lang.String)
	
	@Override
	publicvoidendElement(Stringuri,StringqName)throwsSAXException{

		super.endElement(uri,qName);
		//判断针对一本书是否已经遍历结束
		if(qName.equals("book")){
			
			System.out.println("===========================结束遍历===========================");
		}
	}
	
}

Handler类准备好之后我们来编写测试程序看一下解析结果:

packagetest_XML;

importjava.io.IOException;

importjavax.xml.parsers.ParserConfigurationException;
importjavax.xml.parsers.SAXParser;
importjavax.xml.parsers.SAXParserFactory;
importorg.xml.sax.SAXException;

importHandler.SAXParserHandlerBook;

publicclassTestSAX{

	publicstaticvoidmain(String[]args)throwsParserConfigurationException,SAXException{
	
		try{
			
	//是创建一个Handler处理类,去逐个分析每一个节点,并且是顺序的

	//1.通过SAXParseFactory的静态方法newInstance()来获取SAXParseFactory的实例对象factory
	SAXParserFactoryfactory=SAXParserFactory.newInstance();
		
	//2.通过SAXParserFactory静态方法NewSAXParser()方法返回一个SAXParser类的实例;
	SAXParserHandlerBookhandler=newSAXParserHandlerBook();
	//3.重写startElement、endElement、startDocument、endDocument方法
			/*
			*可以将其保存在继承了DefaultHandler类的SAXParserHandler类中
			*然后创建SAXParserHandler类的对象并将其传入SAXParser类的对象parser的parser方法;
			*/
		SAXParserparser=factory.newSAXParser();
		
		parser.parse("book.xml",handler);
		
		}catch(SAXExceptione){
			
			e.printStackTrace();
			
		}catch(IOExceptione){
			
			e.printStackTrace();
		}
	}
}


以下是解析结果:

SAX解析开始

节点名:bookstore

*************************开始遍历第1本书*************************

第1个属性:

属性名是:id

属性值是:2


第2个属性:

属性名是:type

属性值是:长篇小说


节点名:name

节点值:《平凡的世界》


节点名:author

节点值:路遥


节点名:year

节点值:2014


节点名:price

节点值:22


节点名:outline

节点值:《平凡的世界》是中国作家路遥创作的一部百万字的小说。

===========================结束遍历===========================

*************************开始遍历第2本书*************************

第1个属性:

属性名是:id

属性值是:7


第2个属性:

属性名是:type

属性值是:外文小说


节点名:name

节点值:"Gone with the Wind"


节点名:author

节点值:Margaret.Mitchell


节点名:price

节点值:99


节点名:language

节点值:English


节点名:outline

节点值:《飘》是美国女作家玛格丽特?米切尔(1900―1949)十年磨一剑的作品,也是惟一的作品。


===========================结束遍历===========================

*************************开始遍历第3本书*************************

第1个属性:

属性名是:id

属性值是:13


第2个属性:

属性名是:type

属性值是:中文小说


节点名:name

节点值:《秦腔》


节点名:author

节点值:贾平凹


节点名:price

节点值:99


节点名:language

节点值:汉语


节点名:outline

节点值:《秦腔》以两条线展开,一条线是秦腔戏曲,一条线是农民与土地的关系。


节点值:>


===========================结束遍历===========================

DOM(Document Object Model)是表示和处理一个HTML或XML文档的常用方法,DOM的优势是易用性强,使用DOM这种解析方法的时候,将把所有的XML文档信息都存于内存中,遍历操作简单快速。SAX(Simple API for XML)不是W3C的标准,但是对于大型XML文件的解析效率要高与DOM。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读