質問: 例えば以下のようなXPathがあった場合 ``` "parent::node()/parent::*/@outputclass" "parent::*/parent::*/@outputclass" ``` node() と * の指定の違いによって XPathの結果にどのような違いが出てくるのでしょうか?
回答: 質問の2つのXPathの違いは、`parent::node()`と`parent::*`です.この2つの返すものの違いを説明すれば、それ以降の`parent::*/@outputclass`の結果はそこから自動的に導かれます.この考えに沿って回答を記述します. まず質問にはコンテキストノードが何か?の条件が前提として記述されていません.XML文書では、parent軸で参照されるノードは、存在しないか、ドキュメントノードもしくは要素ノード以外にはありません.従ってコンテキストノードが何かにより`parent::node()`が返すものは異なります. これに対して`parent::*`は、親ノードが要素ノードである場合はそれを返し、ドキュメントノードもしくは存在しない場合は空シーケンスを返します. さて`parent::node()`が何を返すかは、コンテキストノードが何であるかにより以下のパターンとなるでしょう. 1. `self::text()`、`self::processing-instruction()`もしくは`self::comment()`の場合 コンテキストノードがドキュメントノードの子ノードの場合、ドキュメントノードを返します.それ以外の場合は親の要素ノードを返します. 2. `self::element()`の場合 コンテキストノードがドキュメントノードの子ノードの場合(つまりルート要素の場合)、ドキュメントノードを返します.それ以外の場合は親の要素ノードを返します. 3. `self::attribute()`、`self::namespace-node()`の場合 親の要素ノードを返します. 4. `self::document-node()`の場合 空シーケンスを返します. ※ ネームスペース軸はXPath 2.0からdeprecatedとなりましたが、Saxonで試したところ`namespace::node()`で参照できたためカレントコンテキストになり得るものとして扱いました.