Використання 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;"]він нічого не повертає. Чи існує спеціальне правило щодо текстів з " &"?


Чи реальна трансформація XSL нічого не повертає? Або тільки Xpather?
Зак Людина

Відповіді:


89

Схоже, OpenQA , хлопці, які стоять за Selenium, вже вирішили цю проблему. Вони визначили деякі змінні, щоб вони чітко відповідали пробілам. У моєму випадку мені потрібно використовувати XPATH, подібний до //td[text()="${nbsp}"].

Я відтворив тут текст OpenQA щодо цього питання (знайдений тут ):

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

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

Це створює певну проблему в тих рідкісних випадках, коли вам дуже потрібно / потрібно вставити додаткове пробіли у вашому тестовому випадку. Наприклад, вам може знадобитися ввести текст у таке поле: " foo ". Але якщо ви просто <td>foo </td>напишите у свій тестовий зразок Selenese, ми замінимо ваші додаткові пробіли лише одним пробілом.

Ця проблема має просте вирішення. Ми визначили змінну в 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"].


1
Посилання OpenQA більше не успішно завантажується
kjosh

1
Я просто хочу зазначити, що $ {nbsp} не працює для мене в інструментах розробника Selenium або Chrome, а також немає \u00a0. Те, що працювало для мене, було введення нерозривного простору, на mac Alt+Shift+Space. Пошук в Інтернеті говорить Alt+0160про Windows.
Цинік

25

Я виявив, що я можу зробити відповідність, коли я ввожу жорстко закодований пробіл (U + 00A0), ввівши Alt + 0160 у Windows між двома цитатами ...

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

працював для мене із особливим чаром.

З того, що я зрозумів, стандарт XPath 1.0 не обробляє вхідні символи Unicode. Здається, є функції для цього в XPath 2.0, але схоже, Firefox не підтримує його (або я щось неправильно зрозумів). Отже, ви повинні робити з локальною кодовою сторінкою. Потворне, я знаю.

Насправді, схоже, що стандарт покладається на мову програмування за допомогою XPath, щоб забезпечити правильну послідовність виходу Unicode ... Отже, якось я зробив правильно.


Використання Xpather 1.4.1 у Firefox 2 // // td [text () = ''] не дає результатів.
Зак Людина

Вибачте. Це не працює для мене. Моя кінцева мета - використовувати його в Selenium для тестів моїх веб-інтерфейсів. Сам Selenium зберігає тестові вирази в структурі XML, і введення Alt Windows, схоже, втрачає шлях. Також мій & # 160; повертається як XML.
Бержерой

Зак, як я писав, ви повинні замінити пробіл між двома цитатами символом, створеним Alt + 0160 (на цифровій клавіатурі).
PhiLho

4
Треба також успішно працювати з PHP:$col = $xpath->query("//p[text()=\"\xC2\xA0\"]");
Хакре

@Bergory Це працює за допомогою транспортира з драйвером Selenium
Damian Green

4

Спробуйте використовувати десяткову сутність &#160;замість названої сутності. Якщо це не працює, ви можете мати можливість просто використовувати символ unicode для нерозривного простору замість &nbsp;сутності.

(Примітка. Я не пробував цього в XPather, але я спробував це в Oxygen.)


2

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


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

1

Я не можу отримати збіг за допомогою 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.

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


Ви можете редагувати зразок коду так, як це було зроблено для зразка в моєму запитанні. Замініть свою сутність nbsp на & amp; nbsp ;.
Бержерой

1

Шукайте &nbsp;чи тільки nbsp- ви це спробували?


Я усвідомлюю, що це має працювати, але це не зовсім точно, що я знаходжу. У XPATH повинен бути спосіб кодувати певний спосіб, який відповідає тому, що я шукаю.
Бержерой

Можливо, я повинен дивитись на регулярний вираз.
Бержерой

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]"

Довідково

Ви можете знайти відповідне детальне обговорення у:


тл; лікар

Символ Unicode "NO-BREAK SPACE" (U + 00A0)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.