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


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

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

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

6 69

6 ответов:

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

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

более красивым:

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

XPath 2.0 Solutions

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

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

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

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

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

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

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

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

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

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

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