ホームページ  >  記事  >  バックエンド開発  >  XML SAX 解析の詳細な説明

XML SAX 解析の詳細な説明

PHPz
PHPzオリジナル
2017-04-04 10:57:221767ブラウズ



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+")");

}


} '



3、EntityResolverインターフェース:エンティティを解析するために使用される基本インターフェースです。

Java コード コレクション コード

'import java.io.IOException;


import org.xml.sax.EntityResolver;

import org.xml.sax.InputSource;

import org.xml.sax。 SAXException;


public class MyEntityResolverimplements EntityResolver {


/*

* アプリケーションが外部エンティティを解決できるようにします。

* パーサーは、外部エンティティ (最上位のドキュメント エンティティを除く) を開く前にこのメソッドを呼び出します。

* パラメータの意味は次のとおりです:

* 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 java.io.FileReader;

import java.io.IOException;



import org.xml.sax.ContentHandler;

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;

import org.xml.sax.helpers.xmlReaderFactory; g ] args) throws SAXException,

FileNotFoundException {

//ドキュメントコンテンツを処理するためのハンドラーを作成します-関連イベント

ContentHandler contentHandler = new MyContentHandler();

//エラー イベントを処理するハンドラーを作成します

ErrorHandler errorHandler = new MyErrorHandler();

//DTD 関連イベントを処理するハンドラーを作成します

DTDHandler dtdHandler = new MyDTDHandler();

//エンティティリゾルバーを作成します


EntityResolverentityResolver = new MyEntityResolver();


//XML パーサーを作成します (SAX を介して XML を読み取り、解析します)

XMLReader リーダー = XMLReaderFactory。 createXMLReader();

/*

* パーサーの関連機能を設定します

* http://xml.org /sax/features/validation = true は検証機能をオンにすることを意味します

* http://xml .org/sax/features/namespaces = true は、名前空間機能をオンにすることを意味します

*/

reader.setFeature("http:// xml.org/sax/features/validation",true);

reader.setFeature ("http://xml.org/sax/features/namespaces",true);

//XMLパーサーの処理ドキュメントを設定する コンテンツ関連イベントハンドラー

reader.setContentHandler(contentHandler);

// XML パーサーの処理エラー イベント ハンドラーを設定します

reader.setErrorHandler(errorHandler);


//XML パーサーの処理 DTD 関連イベント ハンドラーを設定します

reader.setDTDHandler(dtdHandler);

//XML パーサーのエンティティ パーサーを設定しますXML パーサー

reader.setEntityResolver(entityResolver);

//books.xml ドキュメントを解析します

reader.parse(new InputSource(new FileReader("books.xml")));

}

} '

books.xml ファイルの内容は次のとおりです:

Xml コード コレクション コード



JAVAで考える



Core JAVA2




C++入門
コンソール出力は次のとおりです。


;>> document

エラー (2,7) : ドキュメントが無効です: 文法が見つかりません。

エラー (2,7) : ドキュメントのルート要素 "books"、DOCTYPE ルート "null" と一致する必要があります。


> ;>> start prefix_mapping : xmlns: = "http://test.org/books"

>>> 開始要素 :books(http://test.org/books)

>> ;> 2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\ \\\\\\\ \\\\\\\\\\\\\\\t

>>>>>文字(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)

>>>プレフィックスマッピングの終了:

>>>終了文書

以上がXML SAX 解析の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。