Как я могу использовать XPath, чтобы найти элемент с заголовком, который содержит одинарные и двойные кавычки? - PullRequest
0 голосов
/ 10 марта 2020

У меня есть некоторый код Python / Selenium, который находит элемент с указанным текстом заголовка, используя XPath:

tab_element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_xpath('//a[@title="' + tab_title + '"]'))

В большинстве случаев работает нормально, но не удается, когда встречает элемент с заголовком, который содержит двойные кавычки.

<p title="that'll be the &quot;dayg&quot;">That'll be the "day"</p>

Итак, у меня остается два вопроса:

  1. Как я могу заставить его работать со значениями заголовков, которые содержат двойные кавычки?

  2. Как заставить его работать с любым значением заголовка, например, содержащим как двойные, так и одинарные кавычки?

Ответы [ 2 ]

0 голосов
/ 10 марта 2020

Для XPath 1.0 правило:

(a) строковый литерал не может содержать метку, используемую в качестве разделителя строк; единственный способ обойти это - сформировать строку с помощью concat (), например concat("'", '"', "'") - это строка из трех символов '"'.

(b), если строковый литерал содержит символ, имеющий особое значение в языке хоста (например, " в Java или & в XML), тогда его необходимо экранировать, используя соглашения по экранированию основного языка (\" в Java, &amp; в XML ).

В XPath 2.0 вы можете обойти (a) путем удвоения: например, """" - это строковый литерал, представляющий строку длиной один, содержащую символ двойных кавычек. Вы также можете обойти и (a), и (b), используя функцию codepoints-to-string().

0 голосов
/ 10 марта 2020

Я закончил тем, что использовал функцию экранирования Элиаса XPath из этого потока .

def escape_string_for_xpath(s):
    if '"' in s and "'" in s:
        return 'concat(%s)' % ", '\"',".join('"%s"' % x for x in s.split('"'))
    elif '"' in s:
        return "'%s'" % s
    return '"%s"' % s

escaped_title = escape_string_for_xpath('"that\'ll be the "day"')

driver.find_element_by_xpath('//a[@title=' + escaped_title + ']')
...