1. Document Object Model Traversal

1.1. 概要

この章では、選択的な DOM Level 2 Traversal の特徴について述べる。この TreeWalker, NodeIterator, and NodeFilter インターフェイスは、容易に利用できる、堅牢(robust)な、文書の内容の選択的なトラバーサル(横断?) を提供する。

このセクション内のインターフェイスは強制的な物ではない。DOM アプリケーションは、実装によってこのモジュールがサポートされているかどうかを判定するのに、値 "Traversal" と "2.0" をそれぞれ引数にもつ DOMImplementationhasFeature(feature, version) メソッドを使用できる。このモジュールの完全なサポートのために、DOM Level 2 Core 仕様 [DOM Level 2 Core] で定義される "Core" の特徴を、実装はサポートしなければならない。DOM Level 2 Core 仕様 [DOM Level 2 Core] における 適合 については追加情報を参照されたい。

NodeIteratorTreeWalker は、文書のサブツリーのノードとそれらの存在するノード内の位置をあらわす、2 通りの方法である。NodeIterator は、ドキュメントオーダー内で与えられた序列あるノードの並びとしてのサブツリーの平らな一覧を示す。この一覧は階層へのの考慮なしに示されるので、イテレータは前後に移動するメソッドを持つが、上下に移動するメソッドは持たない。逆に、TreeWalker はこの階層のナビゲーションを許可するサブツリー内の階層関係を維持している。一般に、その中で選択されたノードの周囲の文書構造が操作されるような用途には TreeWalker が向いており、選択された各ノードの内容に注目するような用途には NodeIterator が向いている。

NodeIteratorTreeWalker はそれぞれ、サブツリー内の全ノードを含むとは限らない文書サブツリーの一覧を示す。この仕様では、文書サブツリーそれ自体に該当する 物理一覧(phisical view) と区別するために、これを 論理一覧(logical view) と呼ぶ。イテレータもしくは TreeWalker を作成するとき、各ノードを検査し論理一覧に出現するか否かを決定する NodeFilter に関連付けることができる。加えて、フラグを使用して論理一覧に出現するノード型を指定できる。

NodeIteratorTreeWalker は動的である - 元文書への変更の反映として論理一覧は変化する。しかし、その変更にどう応じるかでそれらは異なる。NodeIterator は連続的にノードを示すものであり、シーケンスの内容が変化するときは、そのシーケンス内の位置に対応するロケーションの維持を試みる。TreeWalker はフィルタをかけられたツリーとしてのノードを示すものであり、ノードが新たなコンテキストに移動する場合は、現在のノードに対応するロケーションとそのノードの付属物の残りを維持する。これらの挙動の詳細は下記にて議論する。

1.1.1. NodeIterators

NodeIterator はノードのリストのメンバが連続的に返されるとことを可能にする。現在の DOM インターフェイス内で、このリストは常に ドキュメントオーダー(document order) 内に示されるサブツリーのノードで構成されるだろう。イテレータが最初に生成されるとき、nextNode() メソッドの呼び出しはサブツリーの論理一覧内の最初のノードを返す; 大抵の場合、これはサブツリーのルートである。連続的な各呼び出しは、リストを通して論理表示内で次に利用可能なノードを返しながら NodeIterator を進める。ノードがなくなったとき、 nextNode()null を返す。

NodeIteratorDocumentTraversal インターフェイスの createNodeIterator メソッドによって生成される。NodeIterator が生成されるとき、ノード型が "visible" であるか、そしてツリー横断中ノードが "invisible" であるかを決定するフラグを使用できる; これらのフラグは OR 演算子で結合できる。イテレータは、"invisible" であるノードを存在しないかのようにスキップする。

次のコードは、イテレータを生成し、関数を呼び出して各要素名をプリントする:

    NodeIterator iter=
     ((DocumentTraversal)document).createNodeIterator(
          root, NodeFilter.SHOW_ELEMENT, null);
    while (Node n = iter.nextNode())
        printMe(n);

1.1.1.1. 前後移動

NodeIterator は序列のあるリストとしてノードを示し、リスト内で前後に移動する。イテレータの位置は常に、最初のノードの前、あるいは最後のノードの後の、どちらか二つのノードの間である。イテレータが最初に生成されるとき、位置は最初の項目の前に設定される。次の図は、イテレータが特定のサブツリーに提供するリスト表示を示す。アスタリスク "*" は位置を示す:

 * A B C D E F G H I

nextNode() 呼び出しは、次のノードを返し、位置を進める。具体的には、上記の位置から開始する場合、最初の nextNode() 呼び出しは "A" を返し、イテレータを進める:

 [A] * B C D E F G H I

返される最も近いノードを 参照ノード(reference node) と呼び、NodeIterator の位置を最もよく表す。イテレータ生成時、最初のノードが参照ノードであり、イテレータは参照ノードの前に位置付けられる。この図では、角括弧([]) が参照ノードを示す。

previousNode() 呼び出しは前のノードを返し、位置は後退する。具体的には、"A" と "B" の間の NodeIterator で開始する場合、"A" が返され、下記の位置に移動する:

 * [A] B C D E F G H I

リストの終端で nextNode() が呼ばれる場合、またリストの先頭で previousNode() が呼ばれる場合、null が返され、イテレータの位置は移動しない。 NodeIterator が最初に生成されたときは、参照ノードは最初のノードである:

 * [A] B C D E F G H I

1.1.1.2. 強健性

ナビゲートするデータ構造が編集されている間、 NodeIterator はアクティブであってよく、イテレータは変更の中でも素直に振舞わねばならない。元のデータ構造の追加および削除は NodeIterator を無効にしない; 実際、 NodeIterator はその detach() メソッドが呼ばれない限りは無効化されない。これを可能にするために、イテレータは参照ノードを用いて位置を維持する。イテレータの状態は、イテレータが参照ノードの前に位置しているか、また後に位置しているかに依存する。

イテレータのリストへの変更が参照ノードを除去しない場合は、 NodeIterator の状態への影響はない。具体的には、イテレータの状態は、イテレータ付近の新たなノードの挿入、また参照ノード以外のノードの削除によっては影響を受けない。次の位置からの開始を考えてみる:

A B C [D] * E F G H I

ここで、"E" を除去してみよう。結果の状態は:

A B C [D] * F G H I

新たなノードが挿入される場合、 NodeIterator は参照ノードに接して位置し、"D" と "F" の間に挿入される場合は、イテレータと "F" の間にそれが発生する:

A B C [D] * X F G H I

ノードの移動は挿入に続く除去と等価である。"I" を "X" の前の位置に移動する場合の結果は:

A B C [D] * I X F G H

参照ノードがイテレートされているリストから取り除かれるならば、異なるノードが参照ノードとして選択される。参照ノードの位置が NodeIterator のイテレータの前ならば、、新しい参照ノードとしてイテレータの直前のノードが選ばれる。次の状態から "D" ノードを取り除くことを考えてみる:

A B C [D] * F G H I

イテレータより前にある NodeIterator に最も近いノードは "C" ノードであるで、これが新しい参照ノードになる:

A B [C] * F G H I

参照ノードが NodeIterator より後にある場合、イテレータの直後のノードが新たな参照ノードとして選択される。 previousNode() が呼出された後など、参照ノードが NodeIterator の後にあるならば、イテレータの後の直近のノードが新しい参照ノードとして選択される。次の状態から始めて "E" を除去することを想定しよう:

A B C D * [E] F G H I

イテレータの後である NodeIterator に最も近いので、 "F" ノードが新しい参照ノードになる:

A B C D * [F] G H I

As noted above, ノードの移動は除去に続く挿入と等しい。次の状態から開始して、 "D" ノードをリストの末尾に移動することを考える:

A B C [D] * F G H I C

結果の状態は次である:

A B [C] * F G H I D

参照ノードがリストの末尾、参照ノードが除去されるとき、一つの特殊なケースが発生する。次の状態から開始して、ノード "C" を除去することを考える:

A B * [C]

与えられた規則に従い、新しい参照ノードは NodeIterator の後の最も近いノードとなるはずであるが、 "C" の後にもうノードはない。同じ状況が previousNode() がリスト内の最初のノードを返したときにも発生する。 Hence: 参照ノードの元の方向にもうノードがないならば、その反対方向の直近のノードが参照ノードとして選ばれる:

A [B] *

NodeIterator が除去されたノードのブロックの内部に位置しているならば、上記の規則は clearly 行われるものであるものをあらわす。具体的には、"C" を "D", "E", "F" の ノードとして、次の状態から "C" を除去することを考える:

A B C [D] * E F G H I D

結果の状態は次である:

A [B] * G H I D

最後に、その からの NodeIteratorroot ノードの除去は、イテレートされているリストを改変せず、イテレータの状態を変更しないことに注意。

1.1.1.3. ノードの可視性

繰り返されているもとのデータ構造は、論理ビューの一部でなく、それゆえ NodeIterator によって返されることはないノードを含んでもよい。ノードが whatToShow フラグの値により除外されるべきであるならば、 nextNode() は除外される "不可視" のノードを飛ばして次の可視のノードを返す。 NodeFilter が存在するならば、それはノードを返す前に適用される; フィルタがノードを受け付けないならば、処理はノードがフィルタに受け入れられ返されるまで繰り返される。遭遇する可視ノードがなくなったら、 null を返してイテレータはリストの末尾に配置される。この場合、参照ノードはそれが可視であるか否かに関係なくリストの最終ノードとなる。反対方向における previousNode() についても同様の対応を取る。

次の例では、小文字を使用してデータ構造内にはあるが論理ビューには存在しないノードをあらわす。具体的には、次のリストを考える:

A [B] * c d E F G

nextNode() 呼出しは E を返し、次の位置に進む:

A B c d [E] * F G

可視でないノードは、参照ノードが除去されてもなお参照ノードとして利用可能である。上記の状態からノード "E" を除くことを考える。結果の状態は:

A B c [d] * F G

可視である新しいノード "X" を "d" の前に挿入することを考える:結果の状態は:

A B c X [d] * F G

previousNode() 呼出しは今度はノード X を返すことに注意。上にあげたように誤ったな結果が返されるなケースがあるため、参照ノードが除去されるときに不可視ノードを飛ばさないことは重要である。 "E" が除去されたとき、新しい参照ノードが "d" ではなく "B" であれば、 previousNode() 呼出しは "X" を返さない。

1.1.2. NodeFilters

NodeFilters は、ユーザにノードを "フィルタで濾す (filter out)" オブジェクトの作成を許可する。各フィルタは、ノードを見てそれが文書のトラバーサルの論理ビューの一部として存在するべきか否かを判定するユーザ定義関数を含む。 NodeFilter を使用して、そのフィルタを使用する NodeIteratorTreeWalker を作成する。トラバーサルエンジンは各ノードにフィルタを適用し、フィルタがノードを拒否すれば、トラバーサルはそのノードが文書内に存在しないかのようにスキップする。 NodeFilters は、操作対象ノードを含む構造のナビゲート方法を知る必要がない。

トラバーサル操作が実行されるとき、また NodeIterator の参照ノードがいてレートされている下位ツリーから除去され新しい参照ノードを選択しなければならないとき、フィルタが調べられる。しかし、これらのフィルタ呼び出しの厳密なタイミングは、ある DOM 実装から他の DOM 実装まで様々である。その理由については、 NodeFilters は過去の呼出しの履歴に基づく状態の維持を試みるべきではない; 結果の振る舞いはポータブルでなくてもよい。

同様に、 TreeWalkersNodeIterators は、過去のフィルタの結果を記憶せず、未来の結果を予測しないように振舞うべきである。トラバーサルロジックがノードを検査する最終時に NodeFilter が試験する条件が変更された (例えば検査する属性の追加削除など) ならば、次のトラバーサル操作が実行されたときのみ可視性の変更が反映する。例えば: 現在のノードのフィルタリングを FILTER_SHOW から FILTER_SKIP に変更する場合、 TreeWalker は任意の方向のそのノードのナビゲートをやめることができるが、フィルタ条件を再び変更しなければそれに戻ることはない。トラバーサル中に変化する NodeFilters を書くこともできるが、その振る舞いは混乱が起こりやすく、可能ならば避けられるべきである。

1.1.2.1. NodeFilters の使用

NodeFilter は、 acceptNode() というメソッドを持ち、 NodeIterator または TreeWalker がフィルタに Node を渡してそれが論理ビュー内に存在するべきか否かを訊くことを許可する。 acceptNode() 関数は Node がどのように扱われるかを説明する 3 この値のうちの一つを返す。 acceptNode()FILTER_ACCEPT を返すならば、 Node は論理ビュー内に存在している; FILTER_SKIP を返すならば、 Node は論理ビュー内には存在しないが、 Node の子は存在してもよい; FILTER_REJECT を返すならば、 Node もその 子孫 も論理ビューには存在しない。イテレータは階層のない序列のあるリストとしてノードをあらわすので、 FILTER_REJECTFILTER_SKIPNodeIterators にとっては同義であり、単に 1 個の現在のノードを飛ばすだけである。

HTML 文書内の名前付きアンカーを受け付けるフィルタを考える。 HTML では、 HREF は NAME 属性を持つ任意の A 要素を参照できる。これは、ノードを見てそれが名前付きアンカーであるかどうかを判定する、 Java による NodeFilter である:

    class NamedAnchorFilter implements NodeFilter
    {
     short acceptNode(Node n) {
      if (n.getNodeType()==Node.ELEMENT_NODE) {
       Element e = (Element)n;
       if (! e.getNodeName().equals("A"))
        return FILTER_SKIP;
      if (e.getAttributeNode("NAME") != null)
        return FILTER_ACCEPT;
       }
        return FILTER_SKIP;
      }
    }

上の NodeFilterNodeIterators でのみ使用されるものであるならば、 FILTER_SKIP のところで FILTER_REJECT を使用してもその振る舞いは変わらない。だが TreeWalker については、 FILTER_REJECT は、名前付きアンカーでない任意の要素の子供を拒否し、名前付きアンカーは常に他の要素に含まれているのでこれは名前つきアンカーを見つけられないことを意味する。 FILTER_SKIP は与えられたノードを拒否するが、その子供の検査を継続する; だから、上述のフィルタは NodeIteratorTreeWalker のどちらでも動作する。

このフィルタを使用するには、ユーザは NodeFilter のインスタンスを生成して、それを使用する NodeIterator を生成する:

NamedAnchorFilter myFilter = new NamedAnchorFilter(); 
NodeIterator iter=
     ((DocumentTraversal)document).createNodeIterator(
          node, NodeFilter.SHOW_ELEMENT, myFilter);

サンプル NodeFilternodeType を検査しているので、この例では SHOW_ELEMENT フラグの使用は厳密には必要ないことに注意。だが文書構造の知識の利点をとることにより SHOW_ELEMENT の使用を無駄にせずに whatToShow パフォーマンスの改善が可能な Traversal インターフェイス実装もありうる。逆に、一方で nodeType 検査をフィルタから除去して、 whatToShow 依存で Elements, Attr, ProcessingInstructions の間の区別するようにもできる。

1.1.2.2. NodeFilters と例外

NodeFilter を書くときは、ユーザは例外を投げるコードを書くのは避けるべきである。だが、 DOM 実装は投げられる例外を防ぐことが出来ないので、例外を投げるフィルタの振る舞いが充分に定義されることが重要である。 TreeWalker または NodeIterator はフィルタによって投げられる例外を受け取らず、また変更しないが、それはユーザのコードまで伝播する。次の関数は NodeFilter を呼出してよく、そしてフィルタによって例外が投げられる場合は例外を伝播してよい:

  1. NodeIterator .nextNode()
  2. NodeIterator .previousNode()
  3. TreeWalker .firstChild()
  4. TreeWalker .lastChild()
  5. TreeWalker .nextSibling()
  6. TreeWalker .previousSibling()
  7. TreeWalker .nextNode()
  8. TreeWalker .previousNode()
  9. TreeWalker .parentNode()

1.1.2.3. NodeFilters と文書変更

充分に設計された NodeFilters は、元の文書構造の変更を行うべきではない。しかし DOM 実装はユーザが文書構造を変更するフィルタコードを書くことを防ぐことが出来ない。トラバーサルはこのケースを扱う特別な処理を提供しない。具体的には、 NodeFilter が文書からノードを削除する場合、なおそのノードを受け付けることができ、それがトラバースされている下位ツリー内にあるとしても NodeIterator または TreeWalker によってそのノードが返されてもよいことを意味する。一般に、この方法は矛盾した混乱する結果を導き、従ってユーザには文書構造を変更しない NodeFilters を書くことを推奨する。代わりに、トラバーサルオブジェクトにより制御されるループ内で編集を行いなさい。

1.1.2.4. NodeFilterswhatToShow フラグ

NodeIteratorTreeWalker は、フィルタを適用する前にその whatToShow フラグを適用する。有効な whatToShow フラグによってノードがスキップされる場合、ノードの評価に NodeFilter が呼出されることはない。この振る舞いが FILTER_SKIP のそれと同様であることに注意; そのノードの子は考慮され、フィルタはそれらの評価に呼出される。 NodeFilter が下位ツリー全体の拒絶を選択するとしても、実際は "スキップ" にあることにも注意; これがアプリケーションに問題を起こす場合、 whatToShowSHOW_ALL に設定すること、そしてフィルタ内部で nodeType を検査することを考えなさい。

1.1.3. TreeWalker

TreeWalker インターフェイスは、 NodeIterator インターフェイスと多くの点で似通った機能を提供する。 2つのインターフェイス間の主な違いは、 TreeWalker は、イテレータのリスト指向のビューではなく、下位ツリー内のノードのツリー指向のビューを提供する。言い換えると、イテレータは前方また後方への移動を許可するが、 TreeWalker はそのノードの へ、またその子のうちの一つへ、また 兄弟 への移動も許可される。

TreeWalker の使用は Node を直接使用したナビゲーションと全く同様であり、2つのインターフェイスのナビゲーションメソッドは類似している。具体的に、これは、まずノードに入った時と子を処理した後で別々の行動をとる、文書オーダー内のノードのツリーを再帰的に歩く関数である:

processMe(Node n) {
   nodeStartActions(n);
   for (Node child=n.firstChild(); 
        child != null;
        child=child.nextSibling()) {
      processMe(child);
   }
   nodeEndActions(n);
}

TreeWalker を使用する同様の処理は、全く同様である。一つだけ違うことがある: TreeWalker 上のナビゲーションが現在の位置を変更すると、関数の末尾の位置が変化する。 currentNode という読書可能アトリビュートは、 TreeWalker の現在のノードに問い合わせと設定の両方を許可する。この関数が完了するとき、 TreeWalker の位置が蓄積されることの保証を使用するだろう:

processMe(TreeWalker tw) {
   Node n = tw.getCurrentNode();
   nodeStartActions(tw);
   for (Node child=tw.firstChild(); 
        child!=null;
        child=tw.nextSibling()) {
      processMe(tw);
   }
   tw.setCurrentNode(n);
   nodeEndActions(tw);
}

Node を直接のナビゲーションする代わりに TreeWalker を使用する利点は、 TreeWalker がツリーの適切なビューの選択をユーザに許可することである。 フラグを使用した CommentsProcessingInstructions の表示・隠蔽ができる; 実体は展開され、また EntityReference ノードとして現れてもよい加えて、 NodeFilters を使用してツリーのカスタムビューを表すこともできる。章によってリストされる、各章内に表が出現することを示す文書のビューをプログラムが必要としているとしよう。このビューの中では、章要素とそれらが含む表だけが見える。最初のステップは、適切なフィルタを書くことである:

class TablesInChapters implements NodeFilter {
   short acceptNode(Node n) {
      if (n.getNodeType()==Node.ELEMENT_NODE) {
          if (n.getNodeName().equals("CHAPTER"))
             return FILTER_ACCEPT;
          if (n.getNodeName().equals("TABLE"))
             return FILTER_ACCEPT;
          if (n.getNodeName().equals("SECT1")
              || n.getNodeName().equals("SECT2")
              || n.getNodeName().equals("SECT3")
              || n.getNodeName().equals("SECT4")
              || n.getNodeName().equals("SECT5")
              || n.getNodeName().equals("SECT6")
              || n.getNodeName().equals("SECT7"))
             return FILTER_SKIP;
      }
      return FILTER_REJECT;
    }
}

このフィルタは TABLE 要素が CHAPTER か SECTn 要素に直接包含されていることを想定している。他の種類の要素に遭遇する場合、それとその子を拒絶する。 SECTn 要素に遭遇する場合、それをスキップするが、それの子は TABLE 要素を包含するかどうかを見るために探索される。

これでプログラムは、この NodeFilter のインスタンスの生成、これを使用する TreeWalker の生成、この TreeWalker を ProcessMe() 関数に渡すことができる:

TablesInChapters tablesInChapters  = new TablesInChapters();
TreeWalker tw  = 
     ((DocumentTraversal)document).createTreeWalker(
          root, NodeFilter.SHOW_ELEMENT, tablesInChapters);
processMe(tw);

(繰り返しになるが、フィルタのロジック内での nodeType の検査と SHOW_ELEMENT の使用の両方を選んでいるのは、前の NodeIterator 例で議論した理由である。)

上の ProcessMe() 関数に変更を加えることなく、 CHAPTER と TABLE 要素を処理する。プログラマは他のフィルタを書いたり他のフラグを設定して異なるノード集合を選択することもできる; 関数がナビゲートに TreeWalker を使用する場合、それは TreeWalker を伴って定義される文書の任意のビューをサポートする。

TreeWalker のフィルタをかけられた文書のビューの構造は、文書自身の構造とは大きく異なっているかもしれないことに注意。例えば、 whatToShow パラメータに SHOW_TEXT だけを指定された TreeWalker は、 Text ノード全てを、 を持たず、互いに 兄弟 であるかのようにあらわす。

1.1.3.1. 強健性

NodeIterator のように、 TreeWalker はそれをナビゲートするデータ構造が編集されている間も有効かもしれず、変更面において優雅に降るまわなければならない。元のデータ構造内の追加と削除は TreeWalker を無効にしない; 実際 TreeWalker はけして無効にされない。

だがそれらの変更への TreeWalker の反応は、 NodeIterator のそれとは全く異なる。繰り返されるリスト内部で NodeIterator がその位置の維持による編集に反応する一方、 TreeWalkers は代わりにその currentNode に据え置く。 TreeWalker のナビゲーションメソッドの全ては、 TreeWalker がアクセスされた最終時から、ノードまたその周囲に何が起ころうとも呼出時の currentNode の文脈条件内で操作する。これは currentNode が本来の下位ツリーの外に移動されたとしても、依然として正しい。

例として、次のような文書片を考えよう:

    ...
    <subtree>
        <twRoot>
            <currentNode/>
            <anotherNode/>
        </twRoot>
    </subtree>
    ...

root ノードが <twRoot/> 要素で、 currentNode が <currentNode/> 要素である TreeWalker を作成した。この図では、上に示されるノードの全ては TreeWalkerwhatToShow とフィルタの設定によって受け入れられると想定する。

removeChild() で <currentNode/> 要素をその から除去する場合、その要素は root ノードの下位ツリー内部でなくても TreeWalkercurrentNode を残す。親のない currentNode が持ちうる任意の子を通してナビゲートする TreeWalker を依然として使用できるが、利用可能な がなくなるため currentNode から外へのナビゲートが出来なくなる。

insertBefore() または appendChild() で <currentNode/> に新しい を与える場合、 TreeWalker ナビゲーションは currentNode の新しい位置から操作する。例えば、 <anotherNode/> 要素の直後に <currentNode/> を挿入した場合、 TreeWalkerpreviousSibling() 操作はそれを <anotherNode/> まで戻し, parentNode() 呼出しはそれを <twRoot/> まで移動するだろう。

currentNode を <subtree/> 要素の中に挿入する場合、そのように:

    ...
    <subtree>
        <currentNode/>
        <twRoot>
            <anotherNode/>
        </twRoot>
    </subtree>
    ...

TreeWalkerroot ノード下から、 currentNode を 外へ移動した。これは TreeWalker を無効にしない; 依然として currentNode に関係するナビゲートに使用してよい。その parentNode() 呼出し操作は、例えば、本来の root ノードの外側であっても、 <subtree/> 要素に移動する。しかしながら、 TreeWalker のナビゲーションが本来の root ノードの下位ツリーの中へ戻るべきならば -- 例えば、 parentNode() 呼出しでなはく nextNode() を呼び、TreeWalker の <twRoot/> 要素へ移動する場合 -- root ノードは TreeWalker を "再捕捉 (recapture)" し、それの外に戻るトラバースを阻止する。

このことはフィルタが使用されていると多少複雑になる。 currentNodeの再配置 -- または新しい currentNode の明示的な選択、または NodeFilter がその決定に基づいている条件内の変更 -- は、文書のフィルタをかけられた (論理) ビュー内で可視ではない currentNode を持つ TreeWalker 内を結果とすることができる。 このノードは、そのビューの "一時的メンバ (transient member)" として考えられる。このノードのナビゲート終了を TreeWalker に問い合わせるとき、結果はちょうどそれが可視であるかのようになるが、条件を可視に再び変更しなければナビゲートでそれに戻ることは出来ないだろう。

特に: currentNode が別な方法でフィルタに拒絶された下位ツリーの一部になる場合、完全な下位ツリーが論理ビューの一時的メンバとして追加されてよい。拒絶された 祖先 を過ぎて上方に移動するまで下位ツリー (全て通常のフィルタリングに従う) 内をナビゲートできる。この振る舞いは、拒絶されたノードがそれが残されるまで (下位ツリー内部でとにかく終えると) 単にスキップされるかのようである; したがって、標準フィルタリングを適用する。

1.2. 公式インターフェイス定義


Issued: / Revised: / All rights reserved. © 2002-2016 TAKI