StAX-ストリームベースのプルXML解析


最近webserviceを勉強していると、多くのフレームワークが発見され、技術はStAXをベースXML解析ツールとして使っているので、今日は資料を見て、簡単に勉強して、ここでまとめてみました.
概要
StAX、フルネーム
Streaming API for XMLは、新しい、ストリームベースのJAVA XML解析標準クラスライブラリです.その最終バージョンは2004年3月にリリースされ、JAXP 1.4(間もなくリリースされるJava 6に含まれる)の一部となった.ある程度、StAXはSAXと同様にXMLイベントに基づく解析方式であり、XMLファイル全体を一度にロードすることはありません.しかし、それらの間にも大きな違いがあります.
SAXと比較
StAXはSAXと同様にXMLイベント解析に基づいているが,DOMがXML全体をメモリにロードするよりも効率的である.異なる点は、StAXはXMLイベントを処理する方法でアプリケーションを最下位に近づけるため、SAXよりも効率的です.
 
SAXを使用する場合,XMLイベントは解析器が開発者を呼び出して作成したコールバックメソッドによって処理されること,すなわちアプリケーションが解析器に受動的であることが分かった.アプリケーションは受動的な待機解析器でXMLイベントを自分の処理にプッシュするしかなく、各イベントについて解析が開始される前に準備する必要があります.この方式を「プッシュ(push)」と呼ぶ.
StAXは正反対で
StAXは、現在のXMLイベントをアプリケーションがプロアクティブに解析器から取得し、より必要な処理(保存または無視)を行う「プル(pull)」方式を採用しています..StAXはアプリケーションに能動権を掌握させ、呼び出しコードを簡略化して所望の内容を正確に処理したり、予期せぬ事故が発生した場合に解析を停止したりすることができる.また、この方法はプロセッサコールバックに基づいていないため、アプリケーションはSAXのように解析器の状態をシミュレートする必要はない.
StAXの応用
以下は、StAXの適用シーンです.http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/index.html
       Data binding
  • Unmarshalling an XML document
  • Marshalling an XML document
  • Parallel document processing
  • Wireless communication

  •     SOAP message processing
  • Parsing simple predictable structures
  • Parsing graph representations with forward references
  • Parsing WSDL

  •     Virtual data sources
  • Viewing as XML data stored in databases
  • Viewing data in Java objects created by XML data binding
  • Navigating a DOM tree as a stream of events

  • 単純な使用
    解析ファクトリの取得
    他の解析技術と同様に、StAX解析器を使用する前に、そのファクトリクラスを取得する必要があります.
    import java.io.InputStream;
    import java.io.OutputStream;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLOutputFactory;
    
    
    public class StAX_Frist {
     public void writeXMlByStream(OutputStream out){
    	 XMLOutputFactory outFactor=XMLOutputFactory.newInstance();//      
    	 .......
     }
    	public void  readXmlByStream(InputStream in){
    		
    		XMLInputFactory inFactory=XMLInputFactory.newInstance();//      
    		.......
    	}

    プライマリAPI
    StAXは、実際にはXMLを処理するAPIの2つのセットを含み、それぞれ異なる程度の抽象を提供しています.ポインタベースのAPIは、アプリケーションがXMLをタグ(またはイベント)として使用できるようにします.ストリームによって処理されます.ここで、解析器はポインタのようにファイルストリーム上を進み、アプリケーションは解析器に従ってファイルの先頭から末尾まで処理することができます.効率は高いが、下位XML構造の抽象を提供していない低層APIです.Cursor APIは2つの主要APIからなり、XMLStreamReaderとXMLStreamWriterは、それぞれXMLInputStreamFacによって構成されています.toryとXMLOutputStreamFactoryが取得します.
    Cursor APIを使用してXMLファイルを読み込みます.
    import java.io.InputStream;
    import javax.xml.stream.XMLInputFactory;;
    import javax.xml.stream.XMLStreamConstants;
    import javax.xml.stream.XMLStreamReader;
    
    
    public class StAX_Frist {
    	
    	public void  readXmlByStream(InputStream in){
    		
    		XMLInputFactory inFactory=XMLInputFactory.newInstance();//      
    		
    
    		try {
    			XMLStreamReader reader=inFactory.createXMLStreamReader(in);//      
    			while(reader.hasNext()){//reader.hasNext();        。
    				int eventId=reader.next();
    				switch (eventId) {
    				case XMLStreamConstants.START_DOCUMENT:
    					System.out.println("start docmuent");
    					break;
    					
    				case XMLStreamConstants.START_ELEMENT:
    					System.out.println("<"+reader.getLocalName()+">");
    					for(int i=0;i<reader.getAttributeCount();i++){
    						System.out.println(reader.getAttributeLocalName(i)+"="+reader.getAttributeValue(i));
    					}
    					break;
    					
    				case XMLStreamConstants.CHARACTERS:
    					if(reader.isWhiteSpace()){
    						break;
    					}
    					System.out.println(reader.getText());
    					break;
    				case XMLStreamConstants.END_ELEMENT:
    					System.out.println("</"+reader.getLocalName()+">");
    					
    					break;
    				case XMLStreamConstants.END_DOCUMENT:
    					System.out.println("end docmuent");
    					break;
    				default:
    					break;
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}

    もう1つは、より高度な反復ベース(Iterator)アプリケーションが一連のイベントオブジェクトとしてXMLを処理し、各オブジェクトとアプリケーションがXML構造の一部を交換することを可能にするAPI.アプリケーションは解析イベントのタイプを特定し、それを対応する特定のタイプに変換し、その方法を利用してそのイベントに属する情報を取得するだけである.イベント反復器に基づく方法はポインタに基づく方法がある重要な利点があります.プロセッサ・イベントを1つのレベルのオブジェクトにすることで、アプリケーションがオブジェクト向けに処理できるようにします.これにより、モジュール化と異なるアプリケーション・コンポーネント間のコード再利用に役立ちます.Iterator APIは、XMLEventReaderとXMLEventWriterの2つの主要なAPIからなり、それぞれXMLInputStreamFactoryとXMLOutputStreamFactoryによって取得される.
    使用
    Iterator API読み取りXMLファイル:
    import java.io.InputStream;
    import java.util.Iterator;
    import javax.xml.stream.XMLEventReader;
    import javax.xml.stream.XMLInputFactory;
    import javax.xml.stream.XMLStreamConstants;
    import javax.xml.stream.events.Attribute;
    import javax.xml.stream.events.Characters;
    import javax.xml.stream.events.StartElement;
    import javax.xml.stream.events.XMLEvent;
    
       public class StAX_Frist {
    	
               public void  readXmlByEvent(InputStream in){
    		
    		XMLInputFactory factory=XMLInputFactory.newInstance();//       
    		try {
    			XMLEventReader reader=factory.createXMLEventReader(in);//     
    			while(reader.hasNext()){
    			XMLEvent event=reader.nextEvent();
    			
    				switch (event.getEventType()) {
    				case XMLStreamConstants.START_DOCUMENT:
    					System.out.println("start docmuent");
    					break;
    					
    				case XMLStreamConstants.START_ELEMENT:
    					StartElement element=(StartElement)event;
    					System.out.println("<"+element.getName().getLocalPart()+">");
    					for(Iterator it=element.getAttributes();it.hasNext();){
    						Attribute attr=(Attribute) it.next();
    						System.out.println(attr.getName().getLocalPart()+"="+attr.getValue());
    					}
    					break;
    					
    				case XMLStreamConstants.CHARACTERS:
    					Characters charData=(Characters)event;
    					if(charData.isIgnorableWhiteSpace()&&charData.isWhiteSpace()){
    						break;
    					}
    					System.out.println(charData.getData());
    					break;
    				case XMLStreamConstants.END_ELEMENT:
    					element=(StartElement)event;
    					System.out.println("</"+element.getName().getLocalPart()+">");
    					
    					break;
    				case XMLStreamConstants.END_DOCUMENT:
    					System.out.println("end docmuent");
    					break;
    				default:
    					break;
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}