Использование XPATH для поиска текста, содержащего - PullRequest
110 голосов
/ 29 октября 2008

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

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

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

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

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

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

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

Ответы [ 6 ]

87 голосов
/ 29 октября 2008

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

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

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

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

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

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

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

23 голосов
/ 29 октября 2008

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

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

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

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

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

4 голосов
/ 29 октября 2008

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

(Примечание: я не пробовал это в XPather, но я пробовал это в Oxygen.)

2 голосов
/ 29 октября 2008

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

1 голос
/ 29 октября 2008

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

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

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

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

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

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

Редактировать: Мой пример кода на самом деле содержит символы '& nbsp;' , но подсветка синтаксиса JavaScript преобразует его в символ пробела. Не вводите в заблуждение!

1 голос
/ 29 октября 2008

Поиск &nbsp; или только nbsp - вы пробовали это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...