JAva値SAX解析xml


SAXは解析速度が速く、メモリの消費量が少ないxml解析器で、Androidなどのモバイル機器に最適です.
SAX解析XMLファイルはイベント駆動を採用している.つまり、完全なドキュメントを解析する必要はない.コンテンツ順にドキュメントを解析する過程で、SAXは現在読んでいる文字がXML文法の一部に合法的かどうかを判断し、合致すればイベントをトリガーする.
イベントとは、ContentHandlerインタフェースに定義されたコールバックメソッドです.
SAXにContentHandlerインタフェースを実装するクラスを提供すれば、そのクラスは通知イベントを得ることができる(実際には、SAXがそのクラスのコールバックメソッドを呼び出した).ContentHandlerはインタフェースなので、使用するときに不便になる可能性があります.そのため、SAXはHelperクラス:DefaultHandlerを制定しました.これはインタフェースを実現しましたが、すべてのメソッドが空です.実現するときは、このクラスを継承し、対応するメソッドを再ロードするだけでいいです.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class ToolXmlBySAX {
	
	public static List<HashMap<String, String>> _readXml(InputStream input, String nodeName){
		try {
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser parser = spf.newSAXParser();
			SaxHandler handler = new SaxHandler(nodeName);
			parser.parse(input, handler);
			input.close();
			return handler.getList();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String[] args) {
		try {
			FileInputStream input = new FileInputStream(new File("itcast.xml"));
			List<HashMap<String, String>> list = _readXml(input, "person");
			for(HashMap<String, String> p : list){
				System.out.println(p.toString());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
SaxHandlerはDefaultHandlerを継承し、xmlファイルの解析を実現する
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxHandler extends DefaultHandler {
	private HashMap<String, String> map = null;
	private List<HashMap<String, String>> list = null;
	/**
	 *           
	 */
	private String currentTag = null;
	/**
	 *          
	 */
	private String currentValue = null;
	private String nodeName = null;
	
	public List<HashMap<String, String>> getList(){
		return list;
	}

	public SaxHandler(String nodeName) {
		this.nodeName = nodeName;
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO             ,       
		list = new ArrayList<HashMap<String,String>>();
	}

	@Override
	public void startElement(String uri, String localName, String name,
			Attributes attributes) throws SAXException {
		// TODO            ,      
		if(name.equals(nodeName)){
			map = new HashMap<String, String>();
		}
		if(attributes != null && map != null){
			for(int i = 0; i < attributes.getLength();i++){
				map.put(attributes.getQName(i), attributes.getValue(i));
			}
		}
		currentTag = name;
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO          XML        
		if(currentTag != null && map != null){
			currentValue = new String(ch, start, length);
			if(currentValue != null && !currentValue.trim().equals("") && !currentValue.trim().equals("
")){ map.put(currentTag, currentValue); } } currentTag=null; currentValue=null; } @Override public void endElement(String uri, String localName, String name) throws SAXException { // TODO , if(name.equals(nodeName)){ list.add(map); map = null; } super.endElement(uri, localName, name); } }
:
startDocument()  ドキュメントの先頭に遭遇した場合、このメソッドを呼び出し、前処理の作業を行うことができます.
endDocument()    上記の方法に対応して、ドキュメントが終了すると、この方法を呼び出して、その中でいくつかの善後の仕事をすることができます.
startElement(String namespaceURI, String localName, String qName, Attributes atts)             開始ラベルを読むと、この方法がトリガーされます.        namespaceURIはネーミングスペース、localNameはネーミングスペースプレフィックスを付けないラベル名、qNameはネーミングスペースプレフィックスを付けたラベル名です.attsにより、すべての属性名と対応する値が得られます.        SAXの重要な特徴は、そのフロー処理です.ラベルに遭遇したとき、以前に遭遇したラベルは記録されません.つまり、startElement()メソッドでは、ラベルの名前と属性、ラベルのネスト構造、上位ラベルの名前、子属があるかどうかなど、他の構造に関する情報は、分からないので、あなたのプログラムが必要です.これにより、SAXはプログラミング処理においてDOMほど便利ではない.       
endElement(String uri, String localName, String name)    このメソッドは上記のメソッドに対応して,終了ラベルに遭遇したときにこのメソッドを呼び出す.
characters(char[] ch, int start, int length)             この方法はXMLファイルで読み込まれたコンテンツを処理するために使用され、最初のパラメータはファイルのコンテンツを格納するために使用され、後の2つのパラメータは読み込まれた文字列のこの配列の開始位置と長さであり、new String(ch,start,length)を使用してコンテンツを取得することができる.
またitcast.xmlは
<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person id="23">
		<name>  </name>
		<age>30</age>
	</person>
	<person id="20">
		<name>   </name>
		<age>25</age>
	</person>
</persons> 
main関数出力は
{id=23, age=30, name=  }
{id=20, age=25, name=   }