Использование XPATH для поиска текста, содержащего  

я использую Браузер XPather чтобы проверить мои выражения XPATH на HTML-странице.

моя конечная цель-использовать эти выражения в Selenium для тестирования моих пользовательских интерфейсов.

я получил HTML-файл с содержимым, подобным этому:

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

Я хочу выбрать узел с текстом, содержащим строку"&nbsp;".

С нормальной строкой, такой как" abc", нет проблем. Я использую XPATH, похожий на //td[text()="abc"].

когда Я пытаюсь с XPATH, как //td[text()="&nbsp;"] он ничего не возвращает. Есть ли специальное правило, касающееся текстов с "&" ?

6 ответов


кажется,OpenQA, ребята за Selenium, уже решили эту проблему. Они определили некоторые переменные, чтобы точно соответствовать пробелы. В моем случае мне нужно использовать XPATH, подобный //td[text()="${nbsp}"].

я воспроизвел здесь текст OpenQA по этому вопросу (найдено здесь):

HTML автоматически нормализуется пробелы внутри элементов, игнорирование начальные/конечные пробелы и преобразования дополнительное пространство, вкладок и строки в единое пространство. Когда Selenium читает текст из страницы, он пытается дублируйте это поведение, чтобы вы могли игнорировать все вкладки и новые строки в ваши утверждения HTML и do основаны на как выглядит текст в браузере, когда оказанный. Мы делаем это, заменяя все невидимые пробелы (включая неразрывное пространство"&nbsp;") С a единое пространство. Все видимые строки (<br>, <p> и <pre> отформатирован новые строки) должны быть консервированный.

мы используем ту же логику нормализацию текст тестового набора HTML Selenese таблицы. Это имеет ряд преимущества. Во-первых, вам не нужно посмотрите на исходный HTML-код страницы выясните, что ваши утверждения должны быть; "&nbsp;" символы невидимы для конечного пользователя, и поэтому вы не должны приходится беспокоиться о них при написании Selenese тесты. (Вам не нужно ставить "&nbsp;" метки в тесте для assertText на поле содержит "&nbsp;".) Вы также можете поставить дополнительные новые строки и пробелы в вашем Selenese <td> теги; так как мы используем то же самое логика нормализации на тест как мы делаем на тексте, мы можем обеспечить что утверждения и извлеченный текст будет соответствовать точно.

это создает небольшие проблемы те редкие случаи, когда вы действительно хотите / нужно вставить дополнительные пробелы в тестовом случае. Например, вы может потребоваться ввести текст в поле, как это: "foo ". Но если вы просто пиши <td>foo </td> в вашей Selenese тестовый случай, мы заменим ваш дополнительные пространства с одним пространством.

эта проблема имеет простое решение. Мы определили переменную в Selenese, ${space}, значение которого равно единице пространство. Вы можете использовать ${space} to вставить пробел, которого не будет автоматически обрезается, вот так: <td>foo${space}${space}${space}</td>. Мы также включили переменную ${nbsp}, который вы можете использовать, чтобы вставить неразрывное пространство.

обратите внимание, что XPaths do не нормализовать пробелы, как у нас. Если вам нужно чтобы написать XPath, как //div[text()="hello world"] но HTML ссылки действительно "hello&nbsp;world", вам потребуется вставить настоящую "&nbsp;" в Тест Selenese, чтобы получить его, чтобы соответствовать, вроде этого: //div[text()="hello${nbsp}world"].


Я обнаружил, что могу сделать совпадение, когда я ввожу жестко закодированное неразрывное пространство (U+00A0), введя Alt+0160 в Windows между двумя кавычками...

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

работал для меня со специальным символом.

из того, что я понял, стандарт XPath 1.0 не обрабатывает экранирование символов Юникода. Кажется, для этого есть функции в XPath 2.0, но похоже, что Firefox не поддерживает его (или я что-то неправильно понял). Таким образом, вы должны иметь дело с локальной кодовой страницей. Гадкий Я знать.

на самом деле, похоже, что стандарт полагается на язык программирования с использованием XPath для обеспечения правильной escape-последовательности Unicode... Так или иначе, я поступил правильно.


попробуйте использовать decimal entity &#160; вместо именованного объекта. Если это не сработает, вы сможете просто использовать Юникоде на неразрывный пробел вместо &nbsp; сущности.

(примечание: Я не пробовал это в XPather, но я попробовал это в кислороде.)


имейте в виду, что совместимый со стандартами XML-процессор заменит любые ссылки на сущности, кроме пяти стандартных XML (&amp;, &gt;, &lt;, &apos;, &quot;) С соответствующим символом в целевой кодировке к моменту вычисления выражений XPath. Учитывая это поведение, предложения PhiLho и jsulak-это путь, если вы хотите работать с инструментами XML. Когда вы входите &#160; в выражении XPath оно должно быть преобразовано в соответствующее последовательность байтов перед применением выражения XPath.


Я не могу получить совпадение с помощью Xpather, но следующее работало для меня с обычными XML и xsl-файлами в XML-блокноте Microsoft:

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

возвращаемое значение равно 1, что является правильным значением в моем тестовом примере.

тем не менее, я должен был объявить nbsp как сущность в моем XML и XSL, используя следующее:

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

Я не уверен, что это поможет вам, но я смог на самом деле найти nbsp С помощью выражение XPath.

Edit: мой пример кода фактически содержит символы ' ' но подсветка синтаксиса JavaScript преобразует его в символ пробела. Не заблуждайтесь!


искать &nbsp; или только