`
chris_freedream
  • 浏览: 32934 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

SAX解析XML file

阅读更多
  • 1. SAX简述
  • 2. SAX in practice


1.SAX简述:
SAX全称Simple API for XML, 用于简单并快速的解析XML文件,是基于事件处理的模型,SUN定义了规范,常用的主要接口包括ContentHandler, ErrorHanlder, XMLReader, XMLFilter, Attributes, InputSource, Locator, 及不常用的EntityResolver, DTDHandler, LexicalHandler, DeclHandler等, UML静态类图如下:
, 也许读者会问,这么多接口都要去实现,并且,很多接口中的方法并不是所要的,那岂不是做无用功, 放心,其中有一个DefaultHanlder已经适配了所有的重要的接口,你只需要继承DefaultHandler并重写你所想处理的方法即可,比如startElement, endElement, charactors等。

其中Apache下的Xerces(http://sax.sourceforge.net/)对这些接口有个集体的实现.
2.SAX in practice

被解析的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<books>
	<book pages="1000" price="$99">
		<name>Thinking in java</name>
		<version>3.0</version>
	</book>
	<book pages="800" price="$40">
		<name>JUnit in Action</name>
		<version>2.0</version>
	</book>
	<book pages="900" price="$70">
		<name>Lucene in Action</name>
		<version>2.0</version>
	</book>
</books>


解析代码如下:
package com.chris.sax.action;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;


import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class XMLParser
{
	//handler normal info.
	protected  PrintStream output =
      new PrintStream( new BufferedOutputStream( new FileOutputStream( java.io.FileDescriptor.out ), 128 ), true );
	//handler error info.
   protected  PrintStream error =
      new PrintStream( new BufferedOutputStream( new FileOutputStream( java.io.FileDescriptor.err ), 128 ), true );
   
   public void parserXMLFile(String fileName ) throws SAXException, IOException
   {
   	XMLReader reader = XMLReaderFactory.createXMLReader();
   	reader.setContentHandler( new MyContentHandler() );
   	reader.setErrorHandler( new MyErrorHandler() );
   	InputSource source = new InputSource( new FileInputStream( new File( fileName ) ) );
   	reader.parse(source);
   }
	
	class MyErrorHandler implements ErrorHandler
	{

		public void error( SAXParseException exception ) throws SAXException
		{
			
			error.println( exception.getMessage() );
		}

		public void fatalError( SAXParseException exception ) throws SAXException
		{

			error.println( exception.getMessage() );
		}

		public void warning( SAXParseException exception ) throws SAXException
		{
			output.println( exception.getMessage() );
			
		}
		
	}
	class MyContentHandler implements ContentHandler
	{
		
	   
		public void characters( char[] ch, int start, int length )
				throws SAXException
		{
			output.print(ch);
		}

		public void endDocument() throws SAXException
		{
			
		}

		public void endElement( String uri, String localName, String name )
				throws SAXException
		{

			output.println("</"+localName+">");
			
		}

		public void endPrefixMapping( String prefix ) throws SAXException
		{

			
		}

		public void ignorableWhitespace( char[] ch, int start, int length )
				throws SAXException
		{
			
		}

		public void processingInstruction( String target, String data )
				throws SAXException
		{
					
		}

		public void setDocumentLocator( Locator locator )
		{
			
		}

		public void skippedEntity( String name ) throws SAXException
		{
			
		}

		public void startDocument() throws SAXException
		{
			output.println("<xml version=\"1.0\" encoding=\"utf-8\"?>");
		}

		public void startElement( String uri, String localName, String name,
											Attributes atts ) throws SAXException
		{
			//uri is identifier of namespace
			//name-->prefix:localName
			output.print("<" +localName );
			for( int i = 0; i < atts.getLength(); i++ )
			{
				String attrName = atts.getLocalName( i );
				String attrValue = atts.getValue( i );
				output.print(" " + attrName + "=" + attrValue );
			}
			output.print(">");
			
		}

		public void startPrefixMapping( String prefix, String uri )
				throws SAXException
		{
			
		}		
	}
	
	public static void main( String[] args ) throws Exception, IOException
	{
		
		XMLParser parser = new XMLParser();
		parser.parserXMLFile("books.xml");
	}
}



解析后的结果如下:
<xml version="1.0" encoding="utf-8"?>
<books>
<books>
	<book pages="1000" price="$99">
		<name>Thinking in java</name>
		<version>3.0</version>
	</book>
	<book pages="800" price="$40">
		<name>JUnit in Action</name>
		<version>2.0</version>
	</book>
	<book pages="900" price="$70">
		<name>Lucene in Action</name>
		<version>2.0</version>
	</book>
</books>
<books>
	<book pages="1000" price="$99">
		<name>Thinking in java</name>
		<version>3.0</version>
	</book>
	<book pages="800" price="$40">
		<name>JUnit in Action</name>
		<version>2.0</version>
	</book>
	<book pages="900" price="$70">
		<name>Lucene in Action</name>
		<version>2.0</version>
	</book>
</books>


这样就把XML文件大体输出到屏幕上来了, 但是你会发现,这些不是你真正想要的结果,甚至出现了乱码,原因就在于characters可能被多次调用,甚至次数不定, 以下是个改进的版本
package com.chris.sax.action;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;


import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class XMLParser
{
	//handler normal info.
	protected  PrintStream output =
      new PrintStream( new BufferedOutputStream( new FileOutputStream( java.io.FileDescriptor.out ), 128 ), true );
	//handler error info.
   protected  PrintStream error =
      new PrintStream( new BufferedOutputStream( new FileOutputStream( java.io.FileDescriptor.err ), 128 ), true );
   
   public void parserXMLFile(String fileName ) throws SAXException, IOException
   {
   	XMLReader reader = XMLReaderFactory.createXMLReader();
   	reader.setContentHandler( new MyContentHandler() );
   	reader.setErrorHandler( new MyErrorHandler() );
   	InputSource source = new InputSource( new FileInputStream( new File( fileName ) ) );
   	reader.parse(source);
   }
	
	class MyErrorHandler implements ErrorHandler
	{

		public void error( SAXParseException exception ) throws SAXException
		{
			
			error.println( exception.getMessage() );
		}

		public void fatalError( SAXParseException exception ) throws SAXException
		{

			error.println( exception.getMessage() );
		}

		public void warning( SAXParseException exception ) throws SAXException
		{
			output.println( exception.getMessage() );
			
		}
		
	}
	class MyContentHandler implements ContentHandler
	{
		
	    private StringBuffer  buffer = new StringBuffer();
	    private String key;
	    
	    
		public void characters( char[] ch, int start, int length )
				throws SAXException
		{
			buffer.append( ch, start, length);
			
		}

		public void endDocument() throws SAXException
		{
			
		}

		public void endElement( String uri, String localName, String name )
				throws SAXException
		{

			if( key.equals( localName))
			{
				output.print(buffer);
			}
			
			output.print("</"+localName+">");

			
			
		}

		public void endPrefixMapping( String prefix ) throws SAXException
		{

			
		}

		public void ignorableWhitespace( char[] ch, int start, int length )
				throws SAXException
		{
			
		}

		public void processingInstruction( String target, String data )
				throws SAXException
		{
					
		}

		public void setDocumentLocator( Locator locator )
		{
			
		}

		public void skippedEntity( String name ) throws SAXException
		{
			
		}

		public void startDocument() throws SAXException
		{
			output.println("<xml version=\"1.0\" encoding=\"utf-8\"?>");
		}

		public void startElement( String uri, String localName, String name,
											Attributes atts ) throws SAXException
		{
			//uri is identifier of namespace
			//name-->prefix:localName
			
			buffer.delete(0, buffer.length());
			key = localName;
			
			output.print("<" +localName );			
			for( int i = 0; i < atts.getLength(); i++ )
			{
				String attrName = atts.getLocalName( i );
				String attrValue = atts.getValue( i );
				output.print(" " + attrName + "=" + attrValue );
			}
			output.print(">");
			
		}

		public void startPrefixMapping( String prefix, String uri )
				throws SAXException
		{
			
		}		
	}
	
	public static void main( String[] args ) throws Exception, IOException
	{
		
		XMLParser parser = new XMLParser();
		parser.parserXMLFile("books.xml");
	}
}


输出结果如下:
<xml version="1.0" encoding="utf-8"?>
<books><book pages=1000 price=$99><name>Thinking in java</name><version>3.0</version></book><book pages=800 price=$40><name>JUnit in Action</name><version>2.0</version></book><book pages=900 price=$70><name>Lucene in Action</name><version>2.0</version></book></books>


当然你可以根据你需求,调整程序使得产生更好的输出.

  • 大小: 12.1 KB
分享到:
评论

相关推荐

    SAX2方法读取XML文件

    SAX2方法读取XML文件,内容非常详实 (read XML file through SAX2 method, and it is in details.)

    sax解析util

    简单的sax解析方式 更灵活的使用 String result = ""; try { String filename = "students.xml"; URL url = Configuration.class.getClassLoader().getResource(filename); String str = url.getFile(); ...

    DIXML v5.9.0 for D6-XE10.1 XML XSLT EXSLT 解析

    SAX and extended reader interfaces. DTD and schema validation. Encoding support for UTF-8, UTF-16, ISO-8859-family, ASCII (all native). XPATH processing. NameSpace support. XSLT transformation and ...

    Android实现向本地写入一个XML文件和解析XML文件

    在网络存储过程中有很多时候会遇到XML文件解析和使用XML保存一些信息,解析XML文件用的比较多的方法是pull解析和SAX解析,但是我一般只用pull解析,下面就向cd卡写入一个XML文件,然后再使用pull解析的方法对文件...

    xml入门教程/xml入门教程

    &1.XML简介 XML的背景 1) XML代表可扩展的标记语言(eXtensible Markup Language); 2) XML由W3C联盟发展维护; 3) XML是一种元语言,可以用来定义其它标签语言; 4) XML没有定义任何标记,它提供了一种工具定义...

    XMLParser:使用 SAX 验证处理来自 XML 文件的客户和订单统计信息

    XML解析器 使用 SAX 验证处理来自 XML 文件的客户和订单统计信息

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2

    3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part3

    3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part4

    3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 ...

    JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part5

    3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个实例 92 3.5.4 第二个实例 94 ...

    kochanparser:我的学校 HTML 时间表的解析器

    除了糟糕的 SAX 解析器实现之外,您可能没有从中得到任何有用的信息。如何使用 File file = new File &#40; " o15.html " &#41;;String xml = file . toString ();TimeTable table = new TimeTable ();table . ...

    Android代码-android-manifest-parser

    一个纯Java、实现了SAX接口、无任何第三方依赖的 AndroidManifest.xml 解析工具。 AndroidManifest.xml文件格式 Binary AndroidManifest.xml Magic Number(0x00080003) 4bytes // 魔数 File Size 4bytes // 文件...

    O r a c l e与X M L

    它对W3C关于XML文档接口的两个主要标准—OM和SAX进行了讨论,同时也涉及到其他相关的XML技术标准如名字空间、XPath以及XSL变换等。随书光盘与Web站点你可以在随书光盘上找到Oracle XDK的产品版,它是相应于Java组件...

    dom4j-jdom封装和解析例子

    * Dom4j(SAX)读取xml数据(解析) * @param params * @throws Exception */ private static List&lt;Pois&gt; getReaderXml(String flg) throws Exception{ String fromRead=Dom4jTest2.class.getClassLoader...

    ruby_rnv:用于Ruby的RelaxNG Compact语法验证器

    结果与Nokogiri SAX解析器集成在一起,可提供高级Ruby。 用法 require 'rnv' validator = RNV :: Validator . new validator . load_schema_from_file &#40; "test/fixtures/test330.rnc" &#41; validator . parse_...

    node_domdocument

    基于出色的 SAX 解析器 expat,由 node-expat 项目为 Node.js 提供,DOMDocument 具有坚实且非常快速的基础。 ##如何使用 var DOMDocument = require ( './path/to/domdocument' ) ; // sorry for not yet ...

    JDK_1_6 API

    javax.xml.transform.sax 此包实现特定于 SAX2 的转换 API。 javax.xml.transform.stax 提供特定于 StAX 的转换 API。 javax.xml.transform.stream 此包实现特定于流和 URI 的转换 API。 javax.xml.validation 此包...

    JavaDemo:java中用到的技术分享demo

    JavaDemo java中用到的技术分享demo #java中解析XML的3中方式 SAX\DOM\StAX 代码位置:com.zdnuist.xmlparse 解析文件位置:file/x1.xml

    老罗android开发视频教程全集百度网盘下载

    【第一版第四章】老罗Android开发视频--解析XML数据(3集) 【第一版第五章】老罗Android开发视频--解析JSON数据(4集) 【第一版第六章】老罗Android开发视频--服务器端JDBC编程(2集) 【第一版第七章】老罗...

    EnToCh:英语译成汉语

    EnToCh英语译成汉语1.词典是file目录下的xml文件;2.使用SAX解析;3.先把解析结果放在Treemap中,并序列化4.以后翻译的时候就可以直接从序列化文件读出结果

Global site tag (gtag.js) - Google Analytics