web-dev-qa-db-ja.com

XPath contains()の使い方は?

私はxpathを勉強しようとしています。私はこの辺で他のcontains()の例を見ましたが、AND演算子を使うものは何もありません。これを機能させることはできません。

//ul[@class='featureList' and contains(li, 'Model')]

に:

...
<ul class="featureList">

<li><b>Type:</b> Clip Fan</li><li><b>Feature:</b> Air Moved: 65 ft.
    Amps: 1.1
    Clip: Grips any surface up to 1.63"
    Plug: 3 prong grounded plug on heavy duty model
    Usage: Garage, Workshop, Dorm, Work-out room, Deck, Office & more.</li><li><b>Speed Setting:</b> 2 speeds</li><li><b>Color:</b> Black</li><li><b>Power Consumption:</b> 62 W</li><li><b>Height:</b> 14.5"</li><li><b>Width:</b> Grill Diameter: 9.5"</li><li><b>Length:</b> 11.5"</li>

<li><b>Model #: </b>CR1-0081-06</li>
<li><b>Item #: </b>N82E16896817007</li>
<li><b>Return Policy: </b></li>
</ul>
...
132
ryeguy

テキスト'Model'を含む可能性のあるli子要素を探すのではなく、持っている照会内の最初のli子を見るだけです。必要なのは、次のようなクエリです。

//ul[@class='featureList' and ./li[contains(.,'Model')]]

このクエリは、テキスト'Model'を含む1つ以上のclassの子を持つfeatureListliを持つ要素を取得します。

187
Jeff Yates

私はすでに+ 1をJeff Yatesの解決策に渡しました。

これがあなたのアプローチがうまくいかない理由の簡単な説明です。この:

// ul [@ class = 'featureList' and contains(li、 'Model')]

contains()関数(またはそれに関するXPathの他の文字列関数)の制限に遭遇します。

最初の引数は文字列です。もしそれにノードリストを与える(それに "li"を与える)と、文字列への変換が行われなければなりません。しかし、この変換はリストの最初のノードに対してのみ行われます。

あなたの場合、リストの最初のノードは<li><b>Type:</b> Clip Fan</li>(文字列に変換されたもの: "Type: Clip Fan")です。

// ul [@ class = 'featureList' and contains(li、 'Type')]]

実際にノードを選択します。

57
Tomalak

これはXPathのcontains()についてのよくある誤解についての古い質問に対する新しい答えです...

要約:contains()部分文字列を含むnotノードを含むを意味します。

詳細な説明

このXPathはよく誤解されています。

//ul[contains(li, 'Model')]

間違った解釈:containsulname__を含むliname__要素を含むModelname__要素を選択します。

これは間違っている

  1. contains(x,y)xname__が文字列であることを期待します。
  2. 複数の要素を文字列に変換するためのXPath規則は this :です。

    ノードセットは、 文書順序 の最初にあるノードセット内のノードの string-value を返すことによって文字列に変換されます。ノードセットが空の場合は、空の文字列が返されます。

正しい解釈:firstulname__要素を選択してください。 - )liname__子には、 文字列値 thatがあります。 )containsModelname__サブストリング。

XML

<r>
  <ul id="one">
    <li>Model A</li>
    <li>Foo</li>
  </ul>
  <ul id="two">
    <li>Foo</li>
    <li>Model A</li>
  </ul>
</r> 

XPath

  • //ul[contains(li, 'Model')]oneulname__要素を選択します。

    注:twoulname__の最初のliname__子のストリング値はtwoname__で、ulname__は含まれていないため、FooModelname__エレメントは選択されません。サブストリング。

  • //ul[li[contains(.,'Model')]]は、onename__およびtwoulname__エレメントを選択します。

    注:contains()は両方のulname__に個別に適用されるため、両方のliname__要素が選択されます。両方のulname__要素に、その文字列値にlisubstringが含まれるModelname__子がなくなり、liname__要素の位置は重要でなくなりました。

また見なさい

6
kjhughes
//ul[@class="featureList" and li//text()[contains(., "Model")]]
0
runrig