web-dev-qa-db-ja.com

XPath-他の要素の後の最初の要素を選択します

私はXPathにかなり慣れていないので、数時間それをいじっていたので、次のようなことができるかどうかは完全にはわかりません。

さて、ここにシナリオがあります:ページからリンクを見つけたいです。そのリンクは、テキスト値によってのみ認識可能です。 <a>タグ間のテキスト(<a href="#">このリンク<a>)。これまでのところ、要素とそのテキストをリンクすることに成功しましたが、唯一の問題はそれらのいくつかが横になっていることです。

これらのリンクは、別のリンクタグが先行する順序付けられていないリストから検出されます。これは、本当に良い"アンカー"最終要素の検索を開始するポイントとして機能します。私が見つけたい(つまり、最初に一致するものを受け入れることができます)

物事を少し明確にするために、ここで何が起こっているかの例を示します:

<a href="#">first dropdown menu</a>
<ul>
  <li><a href="#">some link</a></li>
  <li><a href="#">link i want to find</a></li>
</ul>

<-- *And i would actually want to find the thing from this list* --> 
<a href="#">second dropdown menu</a>
<ul>
  <li><a href="#">some link</a></li>
  <li><a href="#">link i want to find</a></li>
</ul>

そして、私はおそらく、最初の要素が「正しい」要素-私が見つけたい要素である1つの結果または結果のセットのみを受け取りたいと指定する必要があります。

編集:質問はすでに回答されていますが、人々が実際に質問を理解できるように、これをもう少し指定する必要があるというコメントがありました;)

そのため、ドキュメント全体に重複した検索結果が散在する可能性がある別の要素の場所を指定する要素を使用するという考えでした。

基本的に、同じ名前または値を持つ要素を持つドロップダウンメニューのグループから特定のリンクを検索する場合、このようなものに遭遇します。

それは基本的にそれです。ポイントを得るのはまだ少し難しいことを知っていますが、残念ながら、それをもっとうまく説明しようと苦労しています。私は他の誰かがより良い仕事をすることができると確信しています、そして、それが起こるならば、私はここでその説明を含むことを幸せです。

43
JHollanti

私はあなたの質問を何回か読み通さなければなりませんでしたが、私はそれを理解していると思います。興味があるのは述語です。述語を使用すると、条件に基づいてノードを選択できます。

たとえば、次のことができます。

//a[text()='second dropdown menu']/following::ul[1]/li/a[text()='link i want to find']

これは、特定のテキストを含むアンカーを選択し、次のulを見つけて、その子を処理します。

また、結果セット内で位置インデックスを指定できます。次のXPathはデモンストレーションです(ただし、問題は解決しません)。

//a[text()='first dropdown menu']/ul/li[last()]/a/text()

または、軸を使用して兄弟/祖先/子供間を移動できます。

//a[ancestor::ul/preceding::a[1]/text() = 'second dropdown menu']/text()

だから私はあなたの質問を完全に理解したとは思わないが、これはあなたがあなたのXPathを書くのに役立つはずだ。

基本的に、私はあなたのXPathが複数のリストのアンカーと一致し、正しいものを確実に選択したいと思っています。 XPathのある時点で、目的のノードが含まれるリストにのみ当てはまる条件を指定するための述語が必要です。

70

ちょうどそのように私はそれを正しく理解します:あなたは「2番目のドロップダウンメニュー」の後に「いくつかのリンク」ノードが欲しい

ul[preceding::a[text()='second dropdown menu' and position()=last()]]/li/a[text()='link i want to find']

これはトリックを行う必要があります(position()= 1をチェックする必要があることは100%確信していませんが、それを省略すると、preceedingが「すべて」のprecedingノードであるため、後続のすべてのulに一致すると思います-それはあなたのXML構造の残りに依存します)

5
Niko

間違っている場合は修正してください-上記の例から「2番目のドロップダウンメニュー」を選択する必要がありますが、テキストを複製できるため、2番目のドロップダウンメニューのみが必要です。 XPath:

//a[text()='second drop down menu'][2]
0
Dewfy