XPATHを使用して を含むテキストを検索する


120

XPather Browserを使用して、HTMLページのXPATH式をチェックします。

私の最終目標は、これらの式をSeleniumで使用して、ユーザーインターフェイスをテストすることです。

次のような内容のHTMLファイルを取得しました。

<tr>
  <td> abc </ td>
  <td>&nbsp; </ td>
</ tr>

文字列「&nbsp;」を含むテキストを持つノードを選択したい。

「abc」のような通常の文字列では問題はありません。私はと同様のXPATHを使用してい//td[text()="abc"]ます。

私がXPATHを試すと、//td[text()="&nbsp;"]何も返されません。「&」の付いた文章に関する特別なルールはありますか?


実際のXSL変換は何も返しませんか?またはXpatherだけですか?
ザックザヒューマン

回答:


89

Seleniumの背後にいる人々であるOpenQAがすでにこの問題に対処しているようです。彼らは明示的に空白に一致するようにいくつかの変数を定義しました。私の場合、と同様のXPATHを使用する必要があります//td[text()="${nbsp}"]

この問題に関するOpenQAからのテキストをここに再現しました(ここにあります):

HTMLは、要素内の空白を自動的に正規化し、先頭/末尾のスペースを無視して、余分なスペース、タブ、改行を1つのスペースに変換します。Seleniumはページからテキストを読み取るときにこの動作を複製しようとするため、HTMLのすべてのタブと改行を無視し、レンダリング時にブラウザーでテキストがどのように表示されるかに基づいてアサーションを実行できます。これを行うには、すべての非表示の空白(改行しないスペース " &nbsp;"を含む)を1つのスペースに置き換えます。すべての可視改行(<br><p>、および<pre>フォーマットされた新しい行)が保存されなければなりません。

HTML Seleneseテストケーステーブルのテキストにも同じ正規化ロジックを使用します。これには多くの利点があります。まず、ページのHTMLソースを見て、アサーションがどうあるべきかを理解する必要はありません。" &nbsp;"記号はエンドユーザーからは見えないため、セレン語のテストを作成するときにそれらについて心配する必要はありません。( " &nbsp;"を含むフィールドでassertTextを実行するために、テストケースに" "マーカーを配置する必要はありません&nbsp;。)Selenese <td>タグに余分な改行とスペースを配置することもでき ます。テストケースではテキストと同じ正規化ロジックを使用するため、アサーションと抽出されたテキストが正確に一致することを確認できます。

これにより、テストケースに余分な空白を挿入したい/必要とするまれな場合に、少し問題が生じます。たとえば、「foo 」のようなフィールドにテキストを入力する必要がある場合があります。ただし<td>foo </td>、セレン語のテストケースに単純に書き込むと、余分なスペースは1つだけに置き換えられます。

この問題には簡単な回避策があります。Seleneseで変数を定義しました ${space}。その値は単一のスペースです。を使用${space}して、次のように、自動的にトリミングされないスペースを挿入 できます<td>foo${space}${space}${space}</td>${nbsp}改行しないスペースを挿入するために使用できる変数も含まれています 。

XPathは、私たちのように空白を正規化しないことに注意してください。XPathのように記述する必要 //div[text()="hello world"]があるが、リンクのHTMLが本当に " hello&nbsp;world"である場合は、実際の " &nbsp;"をSeleneseテストケースに挿入して、次のように一致させる必要があります //div[text()="hello${nbsp}world"]


1
OpenQAリンクが正常に読み込まれなくなった
kjosh

1
$ {nbsp}がSeleniumやChrome開発ツールで私のために機能していないこと、そしてどちらも機能していないことに注意してください\u00a0。私にとってうまくいったのは、Macで改行しないスペースを入力することでしたAlt+Shift+Space。ウェブ検索はAlt+0160ウィンドウズで言う。
Cynic 2018

25

Windowsで2つの引用符の間にAlt + 0160と入力して、ハードコードされた改行なしスペース(U + 00A0)を入力すると、一致することがわかりました...

//table[@id='TableID']//td[text()=' ']

特別なcharで私のために働いた。

私が理解したところによると、XPath 1.0標準はエスケープするUnicode文字を処理しません。XPath 2.0にはそのための関数があるようですが、Firefoxがそれをサポートしていないようです(または誤解しているようです)。したがって、ローカルコードページを使用する必要があります。醜い、私は知っています。

実際、標準は、XPathを使用して正しいUnicodeエスケープシーケンスを提供するプログラミング言語に依存しているようです...だから、どういうわけか、私は正しいことをしました。


Firefox 2でXpather 1.4.1を使用すると、// td [text()= '']を実行しても結果は得られません。
ザックザヒューマン

ごめんなさい。私にはうまくいきません。私の最終目標は、私のWebインターフェースのテストのためにSeleniumでそれを使用することです。Selenium自体がテスト式をXML構造で保持しており、Alt Windowsのタイピングが途中で失われたようです。また、私の&#160; XMLとしてを返します。
ベルジェロイ2008年

ザック、私が書いたように、2つの引用符の間のスペースを、Alt + 0160(テンキー上)で生成された文字に置き換える必要があります。
PhiLho 2008年

4
PHPでもこれをうまく機能させることができました:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
hakre

@Bergoryこれは、Seleniumドライバーを備えたProtractorを使用して動作します
Damian Green


2

標準準拠のXMLプロセッサは、XMLの5つの標準以外の任意の実体参照を置き換えてしまうことに注意してください(&amp;&gt;&lt;&apos;、は、&quot;ターゲットエンコーディングで対応する文字付き)XPath式が評価される時まで。その動作を考えると、XMLツールを使用したい場合、PhiLhoとjsulakの提案が適切です。&#160;XPath式を入力するときは、XPath式を適用する前に、対応するバイトシーケンスに変換する必要があります。


1
XPather(GUI)またはJavaScript(XMLではないため、エンティティの自動置換なし)でXPathを使用する場合は、そうではありません。他のXML環境(XSTL?)での良いアドバイス。
PhiLho 2008年

1

Xpatherを使用して一致を取得することはできませんが、以下はMicrosoftのXML NotepadのプレーンXMLおよびXSLファイルで機能しました。

<xsl:value-of select="count(//td[text()='&nbsp;'])" />

返される値は1です。これは、私のテストケースでは正しい値です。

ただし、次のようにして、XMLおよびXSL内のエンティティとしてnbspを宣言する必要がありました。

<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>

それが役立つかどうかわかりませんが、XPath式を使用してnbsp実際に見つけることができました。

編集:私のコードサンプルには実際には「&nbsp;」という文字が含まれています しかし、JavaScriptシンタックスハイライトはそれをスペース文字に変換します。誤解しないでください!


私の質問のサンプルに対して行ったように、コードサンプルを編集できます。nbspエンティティを&amp; nbsp;に置き換えます。
ベルジェロイ2008年

1

検索&nbsp;またはのみnbsp-これを試しましたか?


私はこれがうまくいくことを認識していますが、私が何を見つけるのか正確にはわかりません。XPATHには、私が探しているものと一致する特定の方法をエンコードする方法が必要です。
ベルジェロイ2008年

多分私は正規表現に目を向けるべきです。
ベルジェロイ2008年

1

あなたが提供したHTMLに従って:

<tr>
  <td>abc</td>
  <td>&nbsp;</td>
</tr>

文字列でノードを見つけるに&nbsp;は、次のいずれかを使用できます ベースのソリューション:

  • 使用text()

    "//td[text()='\u00A0']"
  • 使用contains()

    "//td[contains(., '\u00A0')]"

ただし、理想的には、NO-BREAK SPACE文字を避け、次のいずれかのロケーター戦略を使用することをお勧めします。

  • <tr>ノードとfollowing-sibling

    "//tr//following-sibling::td[2]"
  • 使用starts-with()

    "//tr//td[last()]"
  • 先行<td>ノードとfollowingnode and後続兄弟の使用`:

    "//td[text()='abc']//following::td[1]"

参照

関連する詳細なディスカッションは次の場所にあります。


tl; dr

Unicode文字「NO-BREAK SPACE」(U + 00A0)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.