先祖
タスク:「great-grandfather」要素fooのid属性を取得します。
通常、そのような場合、彼らは階段を描き始めます:
../../../@id
このようなレコードは、ソースxmlの知識がないと不明瞭なので、悪いです。 このような場合、著者はより有益な表現を使用することをお勧めします。
ancestor::foo[1]/@id
このレコードは、検索対象の要素のアイデアを提供するだけでなく、現在の要素がツリー内でその位置を変更した場合でも機能し続けます。
子孫
タスク:現在の要素でfooの最初の子を見つけます。
StackOverflow.comで同様の質問をすると、2人がすぐに
.//foo[1]
と回答し、他の参加者にサポートされました。 著者は、この表現の不正確さについて介入し、警告しなければなりませんでした。 正解は、
descendant::foo[1]
、その理由は次のとおりです。
.//foo
は、次の式の短縮形です。
self::node()/descendant-or-self::node()/child::foo
エントリ
.//foo[1]
は、fooのすべての子孫を意味し、それぞれが親の最初のfooです 。 このような式は、次のドキュメントの2つの要素を返します。
<リスト> <item> <foo /> </ item> <item> <foo /> </ item> </ list>
descendant::foo[1]
は、1つの要素のみを返します。
この違いはドキュメントに記載されていますが、何らかの理由で多くの人がそれを注意深く見ていません。 エラーを避けるために、著者は常に
.//foo
代わりに
descendant::foo
書くことをお勧めします。ほとんどの場合、これが意味することです。
自己
より短いオプションがある場合、なぜselfが必要なのかと思われます。 (期間)。 ただし、この軸にも用途があります。
タスク:fooと呼ばれる場合、次の要素を取得します。
明らかな解決策:
following-sibling::*[1][name() = 'foo']
著者の意見では、よりエレガントな表現:
following-sibling::*[1]/self::foo
コメントや追加は大歓迎です。