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

120

Я использую браузер XPather для проверки своих выражений XPATH на странице HTML.

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

У меня есть HTML-файл с таким содержанием:

<TR>
  <TD> ABC </ TD>
  <TD> & NBSP; </ TD>
</ TR>

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

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

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

Bergeroy
источник
Ваше фактическое преобразование XSL ничего не возвращает? Или только Xpather?
Zack The Human

Ответы:

89

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

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

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

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

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

У этой проблемы есть простой способ решения. Мы определили переменную в 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"].

Bergeroy
источник
1
Ссылка OpenQA больше не загружается
kjosh
1
Я просто хочу отметить, что $ {nbsp} не работает для меня в инструментах разработки Selenium или Chrome, и тоже \u00a0. Что сработало для меня, так это набрать неразрывный пробел на Mac Alt+Shift+Space. Веб-поиск говорит Alt+0160об окнах.
Cynic
25

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

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

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

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

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

PhiLho
источник
Использование Xpather 1.4.1 в Firefox 2, // td [text () = ''] не дает результатов.
Zack The Human
Сожалею. У меня это не работает. Моя конечная цель - использовать его в Selenium для тестирования моих веб-интерфейсов. Сам Selenium хранит тестовые выражения в XML-структуре, и типизация Alt Windows, похоже, теряется. Кроме того, мой & # 160; возвращается как в XML.
Bergeroy
Зак, как я уже писал, вы должны заменить пробел между двумя кавычками на символ, полученный с помощью Alt + 0160 (на цифровой клавиатуре).
PhiLho
4
$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
Должен
@Bergory.Это работает с использованием Protractor с драйвером Selenium
Дэмиан Грин
4

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

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

Джеймс Сулак
источник
1

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

ChuckB
источник
1
Нет, если вы попробуете / использовать XPath в XPather (GUI) или в JavaScript (без автоматической подстановки сущностей, поскольку мы не в XML). Хороший совет в других средах XML (XSTL?).
PhiLho
1

В соответствии с предоставленным вами HTML:

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

Чтобы найти узел со строкой, &nbsp;вы можете использовать любой из следующих решения на основе:

  • Использование text():

    "//td[text()='\u00A0']"
  • Использование contains():

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

Однако в идеале вы можете избежать символа ПРОБЕЛ БЕЗ РАЗРЫВА и использовать любую из следующих стратегий локатора :

  • Используя родительский <tr>узел и following-sibling:

    "//tr//following-sibling::td[2]"
  • Использование starts-with():

    "//tr//td[last()]"
  • Используя предыдущий <td>узел и followingnode andследующий брат`:

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

Ссылка

Вы можете найти соответствующее подробное обсуждение в:


ТЛ; доктор

Символ Юникода 'NO-BREAK SPACE' (U + 00A0)

DebanjanB
источник
0

Я не могу найти совпадение с помощью 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 преобразует его в пробел. Не вводите в заблуждение!

Зак Человек
источник
Вы можете отредактировать образец кода, как это было сделано для образца в моем вопросе. Замените вашу сущность nbsp на & amp; nbsp ;.
Bergeroy
0

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

Nakilon
источник
Я понимаю, что это должно работать, но не совсем уверен в том, что я нашел. В XPATH должен быть способ кодировать определенный способ, соответствующий тому, что я ищу.
Bergeroy
Может мне стоит поискать регулярное выражение.
Bergeroy
-2

Вы можете использовать XPath Contains, Sibling, Ancestor Functions в Selenium WebDriver для поиска элементов, не имеющих каких-либо уникальных свойств, которые можно идентифицировать.

для более подробной информации прочтите эту страницу: https://www.guru99.com/using-contains-sbiling-ancestor-to-find-element-in-selenium.html

Рагвендра Сону
источник