倭マン's BLOG

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

XML 文書のフォーマット 整理を試みる編 (2) : XMLFormat のプロパティをさらに分類

今回は前回定義した XMLFormat をさらに分類します(一覧)。

使用するノード型、無視できるノード型


XML 文書にはいろいろな型のノードが出てきますが、それらを使用したり、無視したりするのをフォーマットによって指定できるようにしましょう。

個人的には、XML のノードは概ね以下の3種類に分けられると思っています:

  • XML 文書を構成するのに必須のノード
  • 他の型のノードで代替が利くノード
  • 無視できるノード

こう書いてもあまり分からないと思うので、それぞれの種類のノードを具体的に挙げてみると

  • XML 文書を構成するのに必須のノード
    • 要素
    • 属性
    • テキスト
  • 他の型のノードで代替が利くノード
    • 名前空間宣言 (一応属性で代替可能)
    • CDATA セクション (テキストで代替可能)
    • 無視できる空白 (テキストで代替可能)
    • 実体参照 (テキストで代替可能)
  • 無視できるノード
    • 無視できる空白
    • コメント
    • 処理命令 (ホントはしてはいけないけど)
    • DTD

ってな感じです。 「無視できる空白」はダブってますけど。無視できる空白」はテキストノードでも代替できる「他のノードで代替が利くノード」とも考えられそうですが、DTD などによる妥当性検証をした場合にはそうはならないので、「無視できるノード」に分類しました(以下の話では以前から少し変更しています)。

XML 文書を構成するのに必須のノード」はフォーマットのしようがないので以降の話では扱いません。 「他の型のノードで代替が利くノード」と「無視できるノード」をもう少し詳しく見てみましょう。

★他の型のノードで代替が利くノード★

これらのノードを使用するかどうかを指定するプロパティは、XMLFormat クラスに useXxxx() メソッドを定義してアクセスできるようにしましょう:

ノード型 アクセッサメソッド デフォルト値 標準 API などでの対応
名前空間宣言 useNamespaces() true namespaceAware
CDATA セクション useCData() true coalescing (true/false が逆)
実体参照 useEntityReferences() false replacingEntityReferences (true/false が逆)

標準 API などでの対応」は、XML 文書のフォーマット「入力編」「出力編」にある(もしくは機能が似ている)プロパティ名を載せてます(これ以降の表でも同じ)。

★無視できるノード★

これらのノードを無視するかどうかを指定するプロパティは、XMLFormat クラスに ignoreXxxx() メソッドを定義してアクセスできるようにしましょう:

ノード型 アクセッサメソッド デフォルト値 標準 API などでの対応
無視できる空白 ignoreIgnorableWhitespace() false ignoringElementContentWhitespace
コメント ignoreComments() false ignoringComments
処理命令 ignoreProcessingInstructions() false (ignoreTrAXEscapingPIs)
DTD ignoreDTD() false (reportDTDEvents true/false が逆)

正規化できる空白


XML 文書に出てくる空白(空白文字の連なり)には、解析時にフォーマットとして何らかの処理(正規化 normalize)を行っておきたい場合があります。 空白も現れる場所によって分類してみましょう:

  • 境界の空白 (boundary whitespace)
  • 先頭と後尾の空白 (leading and trailing whitespace)
  • 内部の空白 (internal whitespace)

各空白の定義(説明)とそれに対する正規化処理は以下のようになります:

ノード型 説明 正規化処理
境界の空白 ある要素下にあり、その要素の子要素と兄弟関係 (sibling) にある空白のテキストノード 除去する
先頭と後尾の空白 テキストノードの先頭と後尾にある空白(テキストノードの一部) 除去する(trim を行う)
内部の空白 テキストノードの内容で、空白文字でない文字にはさまれた空白(テキストノードの一部) 1つのスペースに変換する

「無視できる空白」を使わない場合(上記の useIgnorableWhitespace() メソッドの返り値が false)の場合、この空白は「境界の空白」となるテキストノードとして返されます。 ただし、これは DTD の妥当性検証と競合してしまう気もします・・・

これらの空白を正規化するかどうかを指定するプロパティは、XMLFormat クラスに normalizeXxxxWhitespace() メソッドを定義してアクセスできるようにしましょう:

ノード型 アクセッサメソッド デフォルト値 標準 API などでの対応
境界の空白 normalizeBoundaryWhitespace() false ignoringBoundaryWhitespace
先頭と後尾の空白 normalizeLeadingAndTrailingWhitespace() false trimText
内部の空白 normalizeInternalWhitespace() false