Нечувствительный к регистру xpath содержит() возможно?

Я просматриваю все текстовые поля моего DOM и проверяю, содержит ли nodeValue определенную строку.

/html/body//text()[contains(.,'test')]

Это чувствительный к регистру. Однако я также хочу поймать Test, Test oder Test. Возможно ли это с помощью XPath (в JavaScript)?

Ответ 1

Это для XPath 1.0. Если ваша среда поддерживает XPath 2.0, см. здесь.


Да. Возможно, но не красиво.

/html/body//text()[
  contains(
    translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),
    'test'
  )
]

Если вы можете, отметьте части текста, которые вас интересуют с помощью других средств, например, заключая их в <span>, который имеет определенный класс.

Если это невозможно, вы можете помочь JavaScript в создании соответствующего выражения XPath:

function xpathPrepare(xpath, searchString) {
  return xpath.replace("$u", searchString.toUpperCase())
              .replace("$l", searchString.toLowerCase())
              .replace("$s", searchString.toLowerCase());
}

xp = xpathPrepare("//text()[contains(translate(., '$u', '$l'), '$s')]", "Test");
// -> "//text()[contains(translate(., 'TEST', 'test'), 'test')]"

(подсказка для шляпы @KirillPolishchuk answer - конечно, вам нужно только перевести те персонажи, которые вы действительно ищете)

Ответ 2

Более красивый:

/html/body//text()[contains(translate(., 'TES', 'tes'), 'test')]

Ответ 3

XPath 2.0 Solutions

  • Используйте нижний регистр():

    /html/body//text()[contains(lower-case(.),'test')]

  • Используйте match() соответствие регулярному выражению с учетом нечувствительности к регистру Флаг:

    /html/body//text()[matches(.,'test', 'i')]

Ответ 4

Да. Вы можете использовать translate для преобразования текста, который вы хотите сопоставить с нижним регистром, следующим образом:

/html/body//text()[contains(translate(., 
                                      'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                      'abcdefghijklmnopqrstuvwxyz'),
                   'test')]

Ответ 5

Если вы используете XPath 2.0, то вы можете указать параметры сортировки в качестве третьего аргумента для метода contains(). Однако URI сортировки не стандартизированы, поэтому детали зависят от продукта, который вы используете.

Обратите внимание, что решения, приведенные ранее с использованием translate(), предполагают, что вы используете только 26-буквенный английский алфавит.

ОБНОВЛЕНИЕ: XPath 3.1 определяет стандартный URI сопоставления для сопоставления без учета регистра.

Ответ 6

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

/html/body//text()[contains(translate(.,'abcdefghijklmnopqrstuvwxyz',
                                        'ABCDEFGHIJKLOMNOPQRSTUVWXYZ'),'TEST')]

надеюсь, что это поможет,