XPathでめったに使用されない3つの軸

XPath言語の主な機能は、ソースドキュメント内の任意の要素にアクセスできる軸にあります。 祖先子孫自己など、めったに使用されない軸の使用を検討してください。

先祖


タスク:「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

コメントや追加は大歓迎です。

Source: https://habr.com/ru/post/J52680/


All Articles