Selenium webdriver Xpath с точкой (.) в имени атрибута

У меня есть следующий html:

<table id="oTable">
<tbody>
    <tr mote.id="12345">
        <td>Status</td>
        <td>1</td>
    </tr>
    <tr mote.id="54321">
        <td>Status</td>
        <td>2</td>
    </tr>
</tbody>

I want to locate the row with mote.id and click the first td-tag

WebElement element = getDriver().findElement(By.xpath("//tr[@mote.id='12345']/td[1]"));

Но я получаю следующую ошибку:

Bad token, expected: ] got: .

person Calle    schedule 24.02.2016    source источник
comment
Попробуйте убрать точку с помощью \.   -  person Jagdeep    schedule 24.02.2016
comment
Вы пытались использовать xpath без mote., как //tr[@id='12345']/td[1]?   -  person Andersson    schedule 24.02.2016
comment
@Andersson Проблема в том, что у меня также есть строка с parentmote.id=12345.   -  person Calle    schedule 24.02.2016
comment
@Calle, предложение Джагдипа о //tr[@mote\.id='12345']/td[1] тоже не работает?   -  person Andersson    schedule 24.02.2016
comment
@Calle, не могли бы вы попробовать получить все строки, а затем использовать метод селена GetAttribute для фильтрации строк из вашего кода? Так что сделайте Driver.FindElements(By.XPath("//table[@id='oTable']/tbody/tr")), а затем используйте цикл for, чтобы пройтись по каждому из них и удалить те, которые либо не имеют атрибута mote.id, либо не имеют правильного значения в атрибуте. Возможно, GetAttribute будет более небрежно относиться к точке в середине атрибута, чем XPath.   -  person Ben C    schedule 24.02.2016
comment
@ Андерссон, нет, я не могу сбежать с помощью \. я получаю недопустимый символ excape   -  person Calle    schedule 24.02.2016
comment
Разве вы не можете напрямую найти элемент td без идентификатора tr? <td>Status</td>   -  person Mosam Mehta    schedule 24.02.2016
comment
@ Калле, ты решил эту проблему?   -  person Ben C    schedule 25.02.2016
comment
Используйте mote\\.id Вам нужно сбежать. с \\   -  person Poojan Dave    schedule 28.06.2017


Ответы (4)


Чтобы найти элемент <td>, используйте:

WebElement element = getDriver().findElement(By.xpath("//td[contains(text(),'Status')]"));
person Mosam Mehta    schedule 24.02.2016

Использовать это:

findElement(By.xpath("//tbody/tr[1]/td[1]")) 

Нет необходимости в mote.id.

Существуют также альтернативные подходы с использованием

findElements(By.tagName("td")).get(0);
person Jagdeep    schedule 24.02.2016
comment
Я думаю, Калле, вероятно, упростил свой пример. Я сомневаюсь, что он стал бы задавать вопрос, может ли такой простой XPath работать. - person Ben C; 24.02.2016
comment
Это правильно @BenChand. Есть много строк, и единственный известный атрибут — это mote.id. - person Calle; 24.02.2016

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

person Prateek    schedule 24.02.2016

Какая у вас версия Selenium? У меня версия 2.52.0 (последняя на данный момент) и Python. Ваш xpath работает:

>>> print driver.find_element_by_xpath("//*[@mote.id='12345']").get_attribute('innerHTML')

        <td>Status</td>
        <td>1</td>
>>>
>>> print driver.find_element_by_xpath("//tr[@mote.id='12345']/td[1]").get_attribute('innerHTML')
Status

В качестве альтернативы вы можете написать вспомогательную функцию, чтобы найти все соответствующие элементы tr, а затем проверить каждый элемент mote.id на наличие нужных вам элементов.

>>> def get_mote_by_id(mote_id):
...     elems = driver.find_elements_by_xpath("//*[@id='oTable']/tbody/tr")
...     for elem in elems:
...         if elem.get_attribute('mote.id') == mote_id:
...             return elem
...
>>>
>>> print get_mote_by_id('12345').get_attribute('innerHTML')

        <td>Status</td>
        <td>1</td>

(Это, очевидно, медленнее, чем xpath, который соответствует напрямую, но если это проблема версии, то это обходной путь.) И да, это на Python, а не на Java, но должно быть ясно, что должна делать версия Java.

PS: Каким образом вы можете заставить своих разработчиков или поставщиков продуктов использовать mote_id или moteid вместо mote.id? Это будет соответствовать именам атрибутов в HTML и XML.

person aneroid    schedule 25.02.2016