倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

org.xml.sax.ext.LexicalHandler

今回は、前回の ContentHandler に続き、XML 文書内のノードを扱うインターフェース org.xml.sax.ext.LexicalHandler を見ていきます(記事一覧)。

org.xml.sax.ext.LexicalHandler インターフェース


LexicalHandler は ContentHandler と違って、通知されてもされなくても「データとしての XML 文書」としては関係のないような SAX イベントを扱います。 LexicalHandler のインターフェース定義は以下の通り:

public interface LexicalHandler{

    void comment(char[] ch, int start, int length) throws SAXException;

    void startCDATA() throws SAXException;
    void endCDATA() throws SAXException;

    void startEntity(String name) throws SAXException;
    void endEntity(String name) throws SAXException;

    void startDTD(String name, String publicId, String systemId) throws SAXException;
    void endDTD() throws SAXException;
}

各メソッドを簡単に見ていきましょう:

メソッド名 説明
comment(char[] ch, int start, int length) コメントが現れたときに呼び出されます。
startCDATA() CDATA セクションの開始時に呼び出されます。
endCDATA() CDATA セクションの終了時に呼び出されます。
startEntity(String name) 略。
endEntity(String name) 略。
startDTD(String name, String publicId, String systemId) 略。
endDTD() 略。

CDATA 関連のメソッドは ContentHandler#characters(..), LexicalHandler#comment(..) とは違い、CDATA セクションの開始と終了を通知する(引数のない)メソッドであることに注意しましょう。 CDATA セクション内の文字列は ContentHandler#characters(..) に渡されます。

LexicalHandler を SAXParser にセットする


作成した ContentHandler(実際には DefaultHandler)を SAX 解析で使用するには SAXParser#parse() メソッドに引数として渡すだけ良いのですが、LexicalHandler は別の方法で設定する必要があります。

LexicalHandler の設定には、SAXParser#setProperty(String, Object) メソッドを用います:

void parser(InputSource input, DefaultHandler dh, LexicalHandler lh) throws Exception{
    SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
    parser.setProperty("http://xml.org/sax/properties/lexical-handler", lh);    //  LexicalHandler の設定
    parser.parse(input, dh);
}

SAXParser#setProperty(String, Object) の引数は以下の通り:

  • 第1引数の文字列は LexicalHandler の設定であることを指定するプロパティ名 "http://xml.org/sax/properties/lexical-handler"。
  • 第2引数は LexicalHandler オブジェクト。