JAVA SAX解析


JAva sax解析
JAVA解析XMLには通常DOMとSAXの2つの方法がある.DOM(ドキュメントオブジェクトモデル)はW 3 C規格であり、標準的な解析方式を提供しているが、その解析効率は常に不十分である.これは、DOMがXMLドキュメントを解析する際に、すべてのコンテンツを一度にメモリにロードし、メモリに存在するツリー構造(ノード数)を構築するためである.解析が必要なXMLドキュメントが大きすぎる場合や、そのドキュメントの一部にのみ興味がある場合は、パフォーマンスの問題が発生します.
SAX(simple API for XML)はXML解析の代替方法である.DOMに比べてSAXは速度が速く,より効率的な方法である.ドキュメントを行ごとにスキャンし、スキャンしながら解析します.また、DOMに比べてSAXはドキュメントを解析する任意の時点で解析を停止することができるが、何事にも逆の側面があり、SAXにとって操作が複雑である
SAXの動作原理
SAXは、インタフェースであり、パッケージでもあるが、インタフェースとして、イベント駆動型XML解析の標準インタフェースであり、SAXの動作原理を変えることなく簡単に言えば、ドキュメント(document)の開始と終了、要素(element)の開始と終了、ドキュメント(document)の開始と終了をスキャンする.終了等でイベント処理関数を通知し、イベント処理関数によって対応する動作を行い、ドキュメントが終了するまで同じスキャンを継続します.
ほとんどのSAXでは、次のようなイベントが発生します.
1.ドキュメントの開始と終了時に、ドキュメント処理イベントがトリガーされます.
2.ドキュメント内の各XML要素が解析を受ける前後に要素イベントがトリガーされます.
3.任意のメタデータは、通常、個別のイベントによって処理される
4.文書のDTDまたはSchemaの処理中にDTDまたはSchemaイベントが発生する.
5.エラーイベントが発生し、ホストアプリケーションにエラーの解析を通知します.
SAX解析ドキュメントプロセスの例
XMLドキュメントの例として
   
  Hello,World!
  

解析のプロセスは次のとおりです.
  1.start document
  2.start element:doc......
  3.start element:para.....
  4.characters:Hello,World!
  5.end element:para......
  6.end element;doc......
  7.end document
解析中のステップごとにイベントが発生し、対応するインタフェースのイベントハンドラがトリガーされます.
プログラムを作成するには、次の手順に従います.
(1).イベントハンドラの作成(つまりContentHandlerの実装クラスを記述し,一般的にDefaultHandlerクラスから継承し,adapterモードを採用する)
(2).SAX解析器の作成
(3).イベントハンドラを解析器に割り当てる
(4).文書を解析し,各イベントをイベントハンドラに送信する.
SAXインタフェースの紹介
ContentHandlerインタフェース(主に使用されるインタフェース)
ContentHandlerは、org.xml.saxパッケージにあるJavaクラスパッケージの特殊なSAXインタフェースです.このインタフェースは、XML解析器がXML入力ドキュメントの解析を開始すると、ドキュメントの先頭と終了、要素の先頭と終了、要素内の文字データなどのイベントなどの特殊なイベントに遭遇するイベント処理方法をカプセル化しています.これらのイベントに遭遇すると、XML解析器はContentHandlerインタフェース内の対応するメソッドを呼び出してイベントを鳴らす.
ContentHandlerインタフェースの方法は次のとおりです.
  void startDocument()              //ドキュメント解析開始の処理
  void endDocument()                //ドキュメント解析終了の処理
  void startElement(String uri, String localName, String qName, Attributes atts) //ElementNodeからの処理
  void endElement(String uri, String localName, String qName)                    //ElementNode終了の処理
  void characters(char[ ] ch, int start, int length)                             //特定のノードでの処理
DTDHandlerインタフェース
DTDHandlerは、基本的なDTD関連イベントの通知を受信するために使用される.このインタフェースはorg.xml.saxパッケージにあります.このインタフェースには、DTDイベントのコメントと未解決のエンティティ宣言セクションのみが含まれます.SAX解析器は、注釈を宣言したり、エンティティを解析しなかったりするときに使用される順序にかかわらず、これらのイベントを任意の順序で報告することができます.ただし、ドキュメントハンドラのstartDocument()イベントの後、最初のstartElement()イベントの前にすべてのDTDイベントをレポートする必要があります.
DTDHandlerインタフェースには、次の2つの方法があります.
  void startDocumevoid notationDecl(String name, String publicId, String systemId) nt()
  void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
EntityResolverインタフェース
EntityResolverインタフェースは、org.xml.saxパッケージに存在するエンティティを解析するための基本インタフェースです.
このインタフェースには、次のような方法が1つしかありません.
  public InputSource resolveEntity(String publicId, String systemId)
このメソッドは、外部エンティティを開く前に呼び出されます.このようなエンティティには、DTD内で参照される外部DTDサブセットおよび外部パラメータエンティティ、およびドキュメント要素内で参照される外部汎用エンティティなどが含まれる.SAXアプリケーションがカスタム処理外部エンティティを実装する必要がある場合は、このインタフェースを実装する必要があります.
ErrorHandlerインタフェース
ErrorHandlerインタフェースはSAXエラーハンドラの基本インタフェースである.SAXアプリケーションがカスタムエラー処理を実行する必要がある場合は、このインタフェースを実装する必要があります.その後、解析器はこのインタフェースを通じてすべてのエラーと警告を報告します.
このインタフェースの方法は次のとおりです.
  void error(SAXParseException exception)          //異なるレベルの処理方法
  void fatalError(SAXParseException exception)
  void warning(SAXParseException exception)
簡単な例:
xmlドキュメント:

<?xml version="1.0"?>
<books>
    <book id="11">
        <name>effective java</name>
        <price>100.3</price>
    </book>
    <book id="12">
        <name>javaScript</name>
        <price>39.3</price>
    </book>
</books>

ドキュメント処理のクラスが必要です.一般的にはcontentHandlerを継承する必要があります.

package com.ming.util.saxparse;

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

public class MyContentHandler extends DefaultHandler {

    private String       preName = null;   //          

    private final String NAME    = "name";

    private final String PRICE   = "prcie";

    private final String BOOK    = "book";

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if (qName.equals(BOOK)) {
            
            // doto           ,            
            System.out.println( BOOK+ ":" + attributes.getQName(0)+" value:"+attributes.getValue(0));
            
        }
        preName = qName;//         
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        preName = null;//            
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (null != preName) {

            String temp = new String(ch, start, length);

            if (preName.equals(NAME)) {
                // doto           ,            
                System.out.println(NAME + ":" + temp);

            } else if (preName.equals(PRICE)) {

                System.out.println(PRICE + ":" + temp);
            }
        }
    }
}

クライアントの呼び出しクラスがもう1つ必要です.

package com.ming.util.saxparse;

import java.io.IOException;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;


public class MySaxParse {
    
    
    public static void main(String[] args) throws SAXException, IOException {
        
        MyContentHandler myHandler = new MyContentHandler();
        
        XMLReader reader = XMLReaderFactory.createXMLReader();
        reader.setContentHandler(myHandler);
        
        //reader.setErrorHandler(myHandler);  //      
        reader.parse("/home/inter12/Templates/test.xml");
        
    }
}

XML Readerは、2つの方法の解析を提供します.
入力ストリーム:

public void parse (InputSource input)
        throws IOException, SAXException;

入力されたのはURIです.この例では、このような方法を採用しています.

 public void parse (String systemId)
        throws IOException, SAXException;