web-dev-qa-db-ja.com

XPath:ドットとtext()の違い

私の質問は、XPathでのドットとtext()の使用に関する詳細です。たとえば、次のfind_element行は同じ要素を返します。

driver.get('http://stackoverflow.com/')

driver.find_element_by_xpath('//a[text()="Ask Question"]')
driver.find_element_by_xpath('//a[.="Ask Question"]')

それで、違いは何ですか? .およびtext()を使用する利点と欠点は何ですか?

47
Andersson

.text()には違いがありますが、入力ドキュメントが原因でこの違いが表面化しない場合があります。

入力ドキュメントが次のようになっている場合(XPath式を考えると想像できる最も単純なドキュメント)

例1

<html>
  <a>Ask Question</a>
</html>

//a[text()="Ask Question"]//a[.="Ask Question"]は、まったく同じ結果を返します。しかし、次のような別の入力ドキュメントを考えてみましょう

例2

<html>
  <a>Ask Question<other/>
  </a>
</html>

a要素には、「質問する」の直後に続く子要素otherもあります。この2番目の入力ドキュメントを考えると、//a[text()="Ask Question"]は引き続きa要素を返しますが、//a[.="Ask Question"]は何も返しません!


これは、2つの述語([]の間のすべて)の意味が異なるためです。 [text()="Ask Question"]は、実際には次を意味します。要素のいずれかのテキストノードに「質問する」というテキストが正確に含まれている場合、trueを返します。一方、[.="Ask Question"]は、要素のstring valueが「Ask Question」と同じ場合にtrueを返すことを意味します。

XPathモデルでは、のように、他の要素がテキストに干渉する場合、XML要素内のテキストを多数のテキストノードに分割できます。例2上記。そこでは、other要素は「質問する」とテキストコンテンツとしてもカウントされる改行文字の間にあります。

さらに明確な例を作成するために、入力ドキュメントとして考えてみましょう。

<a>Ask Question<other/>more text</a>

ここで、a要素には、実際にはtwoテキストノード、「Ask Question」および「more text」が含まれています。両方ともaの直接の子です。これをテストするには、このドキュメントで//a/text()を実行します(----で区切られた個々の結果)。

Ask Question
-----------------------
more text

そのため、このようなシナリオでは、text()は個々のノードのセットを返しますが、述語の.はすべてのテキストノードの文字列連結を評価します。繰り返しますが、パス変数//a[.='Ask Questionmore text']を使用してこの要求をテストすると、a要素が正常に返されます。


最後に、一部のXPath関数では、入力として1つの文字列しか使用できないことに注意してください。 LarsHがコメントで指摘したように、そのようなXPath関数(たとえばcontains())にノードのシーケンスが与えられた場合、firstノードと静かに残りを無視します。

64
Mathias Müller

dot (".")text()には大きな違いがあります:-

  • XPathdot (".")は、コンテキストアイテムを参照するため、 "コンテキストアイテム式"と呼ばれます。これは、ノード(elementattribute、またはtext nodeなど)またはアトミック値(stringnumberなど)と一致する可能性があります。またはboolean)。 text()string形式のelement textのみと一致します。

  • dot (".")表記は、DOMの現在のノードです。これはNode型のオブジェクトになりますが、XPath関数のtext()を使用して要素のテキストを取得すると、firstまでのテキストのみが取得されます内部要素。探しているテキストがinner要素の後にある場合、XPath text()関数ではなく、現在のノードを使用して文字列を検索する必要があります。

例:-

<a href="something.html">
  <img src="filename.gif">
  link
</a>

ここで、テキストlinkを使用してアンカーa要素を検索する場合は、dot (".")を使用する必要があります。 //a[contains(.,'link')]を使用するとアンカーa要素が見つかりますが、//a[contains(text(),'link')]を使用するとtext()関数が見つからないようです。

それがあなたを助けることを願っています.. :)

12
Saurabh Gaur