web-dev-qa-db-ja.com

大文字と小文字を区別しないxpath contains()は可能ですか?

DOMのすべてのテキストノードを実行し、nodeValueに特定の文字列が含まれているかどうかを確認しています。

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

これは大文字と小文字が区別されます。ただし、TestTESTまたはTesTもキャッチしたいです。 XPath(JavaScript)で可能ですか?

81
Aron Woost

これはXPath 1.0用です。ご使用の環境がXPath 2.0をサポートしている場合は、 here をご覧ください。


はい。可能ですが、美しくはありません。

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

可能であれば、特定のクラスを持つ<span>で囲むなど、他の手段でテキストの興味のある部分にマークを付けます。

それが不可能な場合は、適切なXPath式を作成するためにJavaScriptを使用できます。

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's answer -もちろん、実際に文字を翻訳する必要があるだけですsearchingfor)

95
Tomalak

より美しく:

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

XPath 2.0ソリューション

  1. lower-case() を使用:

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

  2. matches() 大文字と小文字を区別しないフラグとの正規表現一致を使用します。

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

47
kjhughes

はい。次のように、translateを使用して、一致させるテキストを小文字に変換できます。

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

XPath 2.0を使用している場合、contains()の3番目の引数として照合を指定できます。ただし、照合URIは標準化されていないため、詳細は使用している製品によって異なります。

Translate()を使用して前述したソリューションはすべて、26文字の英語のアルファベットのみを使用していることを前提としていることに注意してください。

PDATE: XPath 3.1は、大文字と小文字を区別しないマッチングの標準照合URIを定義します。

6
Michael Kay

私がこれを常に行っていたのは、XPathで「変換」機能を使用することでした。非常にきれいだとは言いませんが、正しく動作します。

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

お役に立てれば、

3
Marvin Smit