без учета регистра xpath содержит () возможно? - PullRequest
79 голосов
/ 12 декабря 2011

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

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

Это чувствительно к регистру.Тем не менее, я также хочу поймать Test, TEST oder TesT.Это возможно с XPath (в JavaScript)?

Ответы [ 6 ]

93 голосов
/ 12 декабря 2011

Это для 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')]"

(Шляпа подсказка к @ ответу Кирилла Полищука - конечно, вам нужно перевести только те символы, которые вы на самом деле ищете для)

55 голосов
/ 12 декабря 2011

красивее:

/html/body//text()[contains(translate(., 'TES', 'tes'), 'test')]
46 голосов
/ 30 апреля 2014

Решения XPath 2.0

  1. Использование в нижнем регистре () :

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

  2. Использовать совпадений () регулярное выражение, сопоставленное с его регистром без учета регистра:

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

6 голосов
/ 12 декабря 2011

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

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

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

6 голосов
/ 12 декабря 2011

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

/html/body//text()[contains(translate(., 
                                      'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                      'abcdefghijklmnopqrstuvwxyz'),
                   'test')]
3 голосов
/ 12 декабря 2011

Я всегда делал это с помощью функции «перевод» в XPath. Я не скажу, что это очень красиво, но работает правильно.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...