Существует ли выражение DRYer XPath для объединения? - PullRequest
5 голосов
/ 01 апреля 2011

Это прекрасно работает для поиска HTML-элементов, похожих на кнопки (намеренно упрощено):

  //button[text()='Buy']
| //input[@type='submit' and @value='Buy']
| //a/img[@title='Buy']

Теперь мне нужно ограничить это контекстом.Например, кнопка «Купить», которая появляется внутри поля с надписью:

//legend[text()='Flubber']

И это работает, (.. возвращает нас к содержащему набор полей):

  //legend[text()='Flubber']/..//button[text()='Buy']
| //legend[text()='Flubber']/..//input[@type='submit' and @value='Buy']
| //legend[text()='Flubber']/..//a/img[@title='Buy']

Но есть лиспособ упростить это?К сожалению, такого рода вещи не работают:

//legend[text()='Flubber']/..//(
  button[text()='Buy']
| input[@type='submit' and @value='Buy']
| a/img[@title='Buy'])

(Обратите внимание, что это для XPath в браузере, поэтому решения XSLT не помогут.)

Ответы [ 2 ]

3 голосов
/ 01 апреля 2011

Объединение нескольких условий в одном предикате:

//legend[text()='Flubber']/..//*[self::button[text()='Buy'] or 
                                 self::input[@type='submit' and @value='Buy'] or
                                 self::img[@title='Buy'][parent::a]]

На английском языке:

Выберите всех потомков родителя (или самого родителя) для любого legend элемента, имеющего текст "Flubber", который любой из 1) а button элемент с текстом «Купить» или 2) input элемент, имеющий атрибут type, чье значение равно "submit" и атрибут с именем value, значение которого «Купить» или 3) img, имеющий атрибут с именем title со значением "Купить" и чьим родителем является a элемент.

2 голосов
/ 01 апреля 2011

Из комментариев:

Слегка регулируя, чтобы получить а не IMG: self::a[img[@title='Buy']]. (Сейчас если только «Buy» может быть уменьшено

Используйте это выражение XPath 1.0:

//legend[text() = 'Flubber']/..
   //*[
      self::button/text()
    | self::input[@type = 'submit']/@value
    | self::a/img/@title
    = 'Buy'
   ]

РЕДАКТИРОВАТЬ : Я не видел родительский метод доступа. Только в одном направлении:

//*[legend[text() = 'Flubber']]
   //*[
      self::button/text()
    | self::input[@type = 'submit']/@value
    | self::a/img/@title
    = 'Buy'
   ]
...