DOM と SAX の最後の機能は、Java JavaScript などの言語を使用して、XML ファイル内のノード、テキスト、属性、その他の情報を取得できるようにすることです。
この記事は時間を節約するために他のブログから引用しました。 通常、JAVA で XML を解析するには、DOM と SAX の 2 つの方法があります。 DOM は W3C 標準であり、標準的な解析方法を提供しますが、DOM を使用して XML を解析する場合、パーサーはドキュメント全体を読み取り、メモリ常駐のツリー構造 (ノード ツリー) を構築するため、その解析効率は常に満足のいくものではありませんでした。 ) にすると、コードで DOM の標準インターフェイスを使用してツリー構造を操作できるようになります。しかし、ほとんどの場合、最初に文書全体を解析することなく、文書の一部のみに興味があり、ノード ツリーのルート ノードから必要なデータの一部にインデックスを付けるのにも非常に時間がかかります。
SAX は XML 解析の代替手段です。 Document Object Model DOM と比較して、SAX は XML データを読み取って操作するためのより高速かつ軽量な方法です
。 SAX を使用すると、ドキュメントを読み取ったまま処理できるため、アクションを実行する前にドキュメント全体が保存されるのを待つ必要がありません。 DOM に必要なオーバーヘッドや概念的な飛躍は必要ありません。 SAX API は、データ ストリームの処理、つまりデータ フローに応じてデータを順次処理するのに適したイベントベースの API です。 SAX API
は、ドキュメントの解析中に特定のイベントが発生すると通知します。保存していないデータは、応答すると破棄されます。
以下は、SAX 解析 XML の例です (SAX イベント処理のすべてのメソッドに詳細な注釈が付けられているため、少し長くなります)。SAX API には、イベントを処理するための 4 つの主要なインターフェイスがあります。ContentHandler、DTDHandler です。 、EntityResolver および ErrorHandler。実際、次の例は少し長いかもしれませんが、DefaultHandler クラスを継承し、一部のイベント処理メソッドをオーバーライドする限り、この例の効果を得ることができます。ただし、概要を理解するために、次の例を見てみましょう。 SAX API のすべてのメイン イベント解析メソッドを見てください。 (実際、DefaultHandler は上記の 4 つのイベント ハンドラー インターフェイスを実装し、各抽象メソッドのデフォルト実装を提供します。)
1. ContentHandler インターフェイス: ドキュメントの論理コンテンツの通知を受け取るプロセッサ インターフェイス。
Java コード コレクション コード
'import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException ;
class MyContentHandler は ContentHandler を実装します{
StringBuffer jsonStringBuffer ;
intfrontBlankCount = 0;
public MyContentHandler(){
jsonStringBuffer = new StringBuffer();
}
/*
* 受け取るキャラクターデータのお知らせ。
* DOMでは、ch[begin:end]はTextノードのノード値(nodeValue)に相当します
*/
@Override
public voidcharacters(char[] ch, int begin, int length ) SAXException {
StringBuffer バッファ = new StringBuffer();
for(int i = begin ; i switch(ch[i]){ case '\\\ \\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\':buffer.append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");ブレーク; ケース '\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\r':buffer.append("\\\\\\\\\ \\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\r");ブレーク; ケース'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n':buffer.append("\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\n" );break; case '\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\t':buffer.append("\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\t");break; case '\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\ \"':buffer.append("\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\ "");break; default :buffer.append(ch[i]); } } System.out.println(this.toBlankString(this.frontBlankCount)+ ">> >characters("+length+"): "+buffer.toString()); } /* * ドキュメントの終了の通知を受け取ります。 */ @Override public void endDocument() throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount)+ ">>> ドキュメント終了"); } /* * ドキュメント終了の通知を受け取ります。 * パラメータの意味は次のとおりです: * uri: 要素の名前空間 * localName: 要素のローカル名 (プレフィックスなし) * qName: 要素の修飾名 (プレフィックス付き) prefix) * */ @Override public void endElement(String uri,String localName,String qName) throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount) )+ ">> > 終了要素 : "+qName+"("+uri+")"); } /* * プレフィックス URI 範囲のマッピングを終了します。 */ @Override public void endPrefixMapping(String prefix) throws SAXException { System.out.println(this.toBlankString(--this.frontBlankCount)+ ">>> end prefix_mapping : "+prefix); } /* * 要素コンテンツ内の無視できる空白に関する通知を受け取ります。 * パラメータの意味は次のとおりです: * ch: XML ドキュメントの文字 * start: 配列内の開始位置 * length: 配列から読み取られた文字数 */ @Override public void ignorableWhitespace(char[] ch, int begin, int length) throws SAXException { StringBufferbuffer = new StringBuffer(); for(int i = begin ; i < begin+長さ ; i++) { switch(ch[i]){ case '\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\':buffer.append("\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\ \\\\\");break; case '\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\r':バッファ。 append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\ \\\\\\\\\\\\\r");break; case '\\\\\\\\\\\\\ \\\\\\\\\\\\\\ \\\\\n':buffer.append("\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\n");ブレーク; case '\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\t':buffer.append("\\\\\\\\\ \\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\t");break; case '\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\"':buffer.append("\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\ \"");break; デフォルト:buffer.append(ch[i]); } } System.out.println (this.toBlankString(this.frontBlankCount)+">>> ; ignorable Whitespace("+length+"): "+buffer.toString()); } /* * 通知を受け取る処理命令の。 * パラメータの意味は次のとおりです。 * target: 処理命令のターゲット * data: 処理命令のデータ。指定されていない場合は null です。 */ @Override public void処理命令(String target,String data) throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount)+">>> プロセス命令: (ターゲット = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\"" +ターゲット+"\\\\\ \\\ \\\\\\\\\\\\\\\\\\\\\\\",データ = \\\\\\\\\\\\\\\\\\\\ \\\ \\\\\\\\\""+データ+"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" )") ; } /* * SAX ドキュメント イベントの発生元を見つけるために使用されるオブジェクトを受け取ります。 * パラメーターの意味は次のとおりです。 * locator: 任意の SAX ドキュメント イベントの位置を返すことができるオブジェクト */ @Override public void setDocumentLocator(Locator locator) { System.out. println(this.toBlankString (this.frontBlankCount)+ ">>> set document_locator : (lineNumber = "+locator.getLineNumber() +",columnNumber = "+locator.getColumnNumber() + ",systemId = " +locator.getSystemId() +",publicId = "+locator.getPublicId()+")"); } /* * の通知を受け取るスキップされたエンティティ。 * パラメータの意味は次のとおりです: * name: スキップされるエンティティの名前。パラメーター エンティティの場合、名前は '%' で始まります * 外部 DTD サブセットの場合は、文字列 "[dtd]" になります */ @Override public void SkipedEntity(String name) throws SAXException { System.out.println(this. toBlankString(this.frontBlankCount)+ ">>>skipped_entity : "+name); } /* * ドキュメントの開始の通知を受け取ります。 */ @Override public void startDocument() throws SAXException { System.out.println(this.toBlankString(this.frontBlankCount++)+ ">>> ドキュメントの開始 "); } /* * 要素が開始されたときに通知を受け取ります。 * パラメータの意味は次のとおりです: * uri: 要素の名前空間 * localName: 要素のローカル名 (プレフィックスなし) * qName: 要素の修飾名 (プレフィックス付き) prefix) * atts: 要素の属性コレクション */ @Override public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { System.out.println( this.toBlankString(this.frontBlankCount++)+ ">>> 開始要素 : "+qName+"("+uri+")"); } /* * 開始プレフィックス URI名前空間範囲のマッピング。 * このイベントの情報は、通常の名前空間処理には必要ありません: * http://xml.org/sax/features/namespaces 機能が true (デフォルト) の場合、 * SAX XML リーダーは自動的に要素名と属性名の接頭辞を置き換えます。 * パラメータの意味は次のとおりです。 * prefix: 接頭辞 * uri: 名前空間 */ @Override public void startPrefixMapping(String prefix,String uri) throws SAXException { System. out .println(this.toBlankString(this.frontBlankCount++)+ ">>> start prefix_mapping : xmlns:"+prefix+" = " +"\\\\\\\\\\\\\ \ \\\\\\\\\\\\\\\\\\""+uri+"\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\""); } private String toBlankString(int count){ StringBuffer バッファ = new StringBuffer(); for(int i = 0;i buffer.append(" " "); returnbuffer.toString(); } } ' 2、DTDHandlerインターフェース:DTD関連イベントの通知を受信します。インターフェイス Java コード コレクション コード 'import org.xml.sax.DTDHandler; import org.xml.sax.SAXException; public class MyDTDHandler は DTDHandler { / * * アノテーション宣言イベントの通知を受信します。 * パラメーターの意味は次のとおりです: * name - アノテーション名 * アノテーションのパブリック識別子、または指定されていない場合は null。注釈のシステム識別子、または指定されていない場合は null */ @Override public void notationDecl(String name, String publicId, String systemId) throws SAXException { System.out.println( "> ;>> 表記法宣言 : (name = "+name +",systemId = "+publicId +",publicId = "+systemId+")"); } * 未解決のエンティティ宣言イベントの通知を受け取ります。 * パラメーターの意味は次のとおりです: * name - 未解決のエンティティの名前。 * publicId - エンティティの公開識別子、または指定されていない場合は null。 * systemId - エンティティのシステム識別子。 * notationName - 関連するアノテーションの名前。 */ @Override public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException { System.out.println(">>>) ;解析されていないエンティティ宣言: (name = "+name +",systemId = "+publicId +",publicId = "+systemId +",notationName = "+notationName+")"); } Java コード コレクション コード 'import java.io.IOException; import org.xml.sax.InputSource; import org.xml.sax。 SAXException; * アプリケーションが外部エンティティを解決できるようにします。 * パーサーは、外部エンティティ (最上位のドキュメント エンティティを除く) を開く前にこのメソッドを呼び出します。 * パラメータの意味は次のとおりです: * publicId: 参照される外部エンティティの公開識別子、または null の場合は null提供されていない 。 * systemId: 参照される外部エンティティのシステム識別子。 * 戻り値: * 新しい入力ソースを記述する InputSource オブジェクト、またはシステム識別子への通常の URI 接続を開くようにパーサーに要求する null *。 */ @Override public InputSourcesolveEntity(String publicId, String systemId) throws SAXException, IOException { return null; } } 4、ErrorHandlerインターフェース: は、エラー ハンドラーの基本インターフェイスです。 Java コード コレクション コード import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class MyErrorHandlerimplements ErrorHandler { + e.getLineNumber()+"," +e.getColumnNumber()+") : "+e.getMessage()); /* * 回復不可能なエラーの通知を受け取ります。 */ @Override public void fatError(SAXParseException e) throws SAXException { System.err.println("FatalError ("+e.getLineNumber()+"," +e.getColumnNumber() +") : "+e.getMessage()); /* * 回復不可能なエラーの通知を受け取ります。 */ @Override public void warning(SAXParseException e) throws SAXException { System.err.println("Warning ("+e.getLineNumber()+"," +e.getColumnNumber() +") : "+e.getMessage()); } Test クラスの main メソッドは、books.xml を解析するときにイベント情報を出力します。 Java コードコレクションコード import java.io.FileNotFoundException; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax. SaxException; import org.xml.sax.xmlReader; //XML パーサーを作成します (SAX を介して XML を読み取り、解析します) XMLReader リーダー = XMLReaderFactory。 createXMLReader(); reader.setDTDHandler(dtdHandler); //XML パーサーのエンティティ パーサーを設定しますXML パーサー reader.setEntityResolver(entityResolver); //books.xml ドキュメントを解析します reader.parse(new InputSource(new FileReader("books.xml"))); } Xml コード コレクション コード JAVAで考える C++入門 ;>> document エラー (2,7) : ドキュメントが無効です: 文法が見つかりません。 >>> 開始要素 :books(http://test.org/books) >>>>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>開始要素: book(http://test.org/books) >>>文字(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t >>>開始要素: name(http://test.org/books) >>>文字(16): JAVAで考える >>>終了要素: name(http://test.org/books) >>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>終了要素: book(http://test.org/books) >>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>開始要素: book(http://test.org/books) >>>文字(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t >>>開始要素: name(http://test.org/books) >>>文字数(10): コア JAVA2 >>>終了要素: name(http://test.org/books) >>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>終了要素: book(http://test.org/books) >>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>開始要素: book(http://test.org/books) >>>文字(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t >>>開始要素: name(http://test.org/books) >>>文字(10): C++ 入門 >>>終了要素: name(http://test.org/books) >>>文字(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t >>>終了要素: book(http://test.org/books) >>>文字(1): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n >>>終了要素:books(http://test.org/books) >>>プレフィックスマッピングの終了: >>>終了文書
/ *
} '
3、EntityResolverインターフェース:エンティティを解析するために使用される基本インターフェースです。
import org.xml.sax.EntityResolver;
public class MyEntityResolverimplements EntityResolver {
/*
import org.xml.sax.ContentHandler;
EntityResolverentityResolver = new MyEntityResolver();
//XML パーサーの処理 DTD 関連イベント ハンドラーを設定します
Core JAVA2
コンソール出力は次のとおりです。
> ;>> start prefix_mapping : xmlns: = "http://test.org/books"
以上がXML SAX 解析の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。