Нечувствительный к регистру 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')]
надеюсь, что это поможет,