ここでXPath contains()を使用する方法?


142

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>
...

これは私にとってはうまくいきます、私はwhitebeam.org/library/guide/TechNotes/xpathtestbed.rhtmで
mihi

回答:


199

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

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

このクエリは、テキストを含む1つ以上の子を持つa classfeatureList持つ要素を提供します。li'Model'


13
+1-"./"は少し誤解を招く-現在のノード以外のものが除外されると考慮されることを示唆していますが、実際には冗長です: "// ul [@ class = ' featureList 'とli [contains(。、' Model ')]] "は同じものです。
Tomalak、2009年

4
うん、私はただ具体的でした。かなり具体的すぎる可能性があります。
ジェフイエーツ

何がある場合liModelではul、そのand条件は失敗します。だからandコンディションが戻るfalse空のセットに、それが正しいのですか?
damluar 2014年

58

私はすでにジェフイェイツのソリューションに+1を与えました。

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

// 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')]

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


1
「.//td[contains(.//*,'something ')]」のようなクエリが1の深さまでしか機能しない理由を理解するのに苦労している素晴らしい人は、それを機能させる方法を理解しましたが、実際には機能しませんでした上記がどのように機能していたかを確認してください。私が実際に必要としたのは、「.// td [.//* [contains(。、 'something')]]」
JonnyRaa

11

これは、XPath に関する一般的な誤解についての古い質問に対する新しい回答contains()です...

概要:contains()手段は、サブストリングが含まれているいない ノードが含まれています

詳細説明

このXPathはしばしば誤って解釈されます。

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

間違った解釈: これらの選択ul要素を含んliで要素をModelその中に。

これは間違っている

  1. contains(x,y)x文字列であることを期待し、
  2. 複数の要素を文字列に変換するためのXPathルールは次のとおりです。

    ドキュメントセットの最初にあるノードセット内のノードの文字列値を返すことにより、ノードセットは文字列に変換されます。ノードセットが空の場合、空の文字列が返されます。

右の解釈:これらの選択ul要素最初の li子がある文字列値が含まれModelたサブストリングを。

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> 

XPaths

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

    注意:two ul要素が選択されていないので、最初の文字列値liの子two ulであるFoo含まない、Model部分文字列を。

  • //ul[li[contains(.,'Model')]]oneおよびtwo ul要素を選択します。

    注:それぞれに個別に適用ulされるため、両方の要素が選択contains()されますli。(したがって、トリッキーな複数要素から文字列への変換ルールは回避されます。)両方のul要素にはli、文字列値にModelサブストリングが含まれる子がありますli。要素の位置は重要ではなくなりました。

こちらもご覧ください


-2
//ul[@class="featureList" and li//text()[contains(., "Model")]]

-5

containsここに私の例を貼り付けます:

//table[contains(@class, "EC_result")]/tbody

2
OPのコードにtable要素またはEC_resultクラスの値はありません。 この回答はここでは意味がなく、削除する必要があります。
kjhughes
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.