倭マン's BLOG

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

XMLStreamReader をもう少し詳しく (1): getEventType(), isXxxx() メソッド

今回から何回かにわたって、javax.xml.stream.XMLStreamReader の挙動を見ていきます(一覧)。

予定としては

  1. getEventType(), isXxxx() メソッド
  2. hasXxxx() メソッド
  3. nextTag() メソッド
  4. getElementText() メソッド
  5. 要素の名前に関するメソッド(getName(), getPrefix(), getLocalName(), getNamespaceURI() メソッド)
  6. require() メソッド
  7. getAttributeXxxx() メソッド
  8. getNamespaceXxxx() メソッド
  9. getTextXxxx() メソッド
  10. その他のメソッド

の順に見ていきます(変更の可能性アリ)。 今回は「getEventType() メソッド」と「isXxxx() メソッド」。

getEventType() メソッド


getEventType() メソッドは現在の XML イベントに応じて XMLStreamConstants に定義された定数(int 値)を返します。

実装例:

    private int eventType;

    public int getEventType() {
        return this.eventType;
    }

isXxxx() メソッド


isXxxx() メソッドは、オブジェクトの状態を確認するメソッドです。 (ほぼ例外なく)boolean 値を返します。 ここでは特に、解析中の状態がどの XML イベントなのかを確認する以下のメソッドを考えます:

  • isStartElement()
  • isEndElement()
  • isCharacters()
  • isWhiteSpace()

これら以外の isXxxx() メソッドとして

  • isStandalone()
  • isAttributeSpecified()

というものがありますが、これらはそれぞれ START_DOCUMENT, ATTRIBUTE イベントの状態を取得するメソッドなのでここでは割愛します。

★isStartElement(), isEndElement() メソッド★

isStartElement(), isEndElement() メソッドは、現在の XML イベントがそれぞれ要素の開始 (START_ELEMENT)、要素の終了 (END_ELEMENT) ならば true を、そうでなければ false を返します。

実装例

    public boolean isStartElement() {
        return getEventType() == START_ELEMENT;
    }

    public boolean isEndElement() {
        return getEventType() == END_ELEMENT;
    }

★isCharacters() メソッド★

isCharacters() メソッドは、現在の XML イベントが文字データ (character data) なら true を、そうでないなら false を返します。 StAX API では、文字データとみなされる XML イベントの定数は CHARACTERS, CDATA, SPACE です。

実装例

    public boolean isCharacters() {
        switch(getEventType()){
            case CHARACTERS:
            case CDATA:
            case SPACE:
                return true;
            default:
                return false;
        }
    }

★isWhiteSpace() メソッド★

isWhiteSpace() メソッドは、現在のイベントが文字データであり、かつそれが空白文字 (whitespace character) だけからなっていれば true を、そうでなければ false を返します。 もう少し詳しく書くと

  • CHARACTER, CDATA → 空白文字だけからなっていれば true、そうでなければ false を返す
  • SPACE*1 → true を返す
  • それ以外 → false を返す

となります。

実装例

    public boolean isWhiteSpace() {
        switch(getEventType()){
            // CHARACTERS, CDATA の場合は whitespace かどうかを判定
            case CHARACTERS:
            case CDATA:
                if(getText().length == 0)
                    return false;
                else
                    return getText().trim().isEmpty();

            // 無視できる空白 (ignorable whitespace) の時は常に true
            case SPACE:
                return true;

            // それら以外は常に false
            default:
                return false;
        }
    }

2つほど注意を:

  • CHARACTER, CDATA の場合に getText() で返される文字列が空かどうかをテストしてます (if(getText().length == 0)...) 。 getText() メソッドの返り値が空文字列となることは一見なさそうですが、内容のない CDATA セクション があると起こりえます。 空の文字列は空白とはみなさないので false を返しています。
  • 上記の例では、文字列が空白かどうかを判定するのに getText().trim().isEmpty() としています。 java.lang.String#trim() メソッドを使って XML の空白を判定していることに違和感があるかもしれませんが、それが妥当なことはこちらを参照してください。

*1:XMLStreamConstants.SPACE は「無視できる空白(ignorable whitespace)」を表します。