XPath include () nasıl kullanılır?


142

XPath öğrenmeye çalışıyorum. contains()Buradaki diğer örneklere baktım , ancak AND operatörü kullanan hiçbir şey yoktu . Bunu çalıştıramıyorum:

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

Açık:

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

Yanıtlar:


199

Metin içerebilecek liherhangi bir lialt öğeyi aramak yerine, sorgudaki yalnızca ilk alt çocuğa bakıyorsunuz 'Model'. İhtiyacınız olan şey aşağıdaki gibi bir sorgudur:

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

Bu sorgu size sahip elemanlar verecek classait featureListbir veya daha fazla olan li, metin içeren çocuklar 'Model'.


13
+1 - "./" biraz yanıltıcıdır - bu düğümü bıraktığınızda geçerli düğümden başka bir şeyin dikkate alınmasını önerir, ancak aslında gereksizdir: "// ul [@ class = ' featureList 've li [içerir (.,' Model ')]] "" aynı şeydir.
Tomalak

4
Evet, sadece spesifik oluyordum. Büyük olasılıkla aşırı belirgin.
Jeff Yates

Hiçbir varsa liile Modelin ul, daha sonra andkoşul başarısız olur. Yani anddurum döndürür falseboş sette, bu doğru mu?
damluar

58

+ 1'imi Jeff Yates'in çözümüne verdim.

İşte yaklaşımınızın neden işe yaramadığına dair kısa bir açıklama. Bu:

// ul [@ class = 'featureList' ve içerir (li, 'Model')]

contains()işlevin bir sınırlamasıyla (veya bu konu için XPath'de başka bir dize işleviyle) karşılaşırsa.

İlk argümanın bir dize olması gerekiyordu. Bir düğüm listesi beslerseniz (" li" bunu verirse ), dizeye bir dönüşüm gerçekleşmelidir. Ancak bu dönüşüm yalnızca listedeki ilk düğüm için yapılır.

Sizin durumunuzda listedeki ilk düğüm <li><b>Type:</b> Clip Fan</li>(bir dizeye dönüştürülür: " Type: Clip Fan"), bu şu anlama gelir:

// ul [@ class = 'featureList' ve içerir (li, 'Type')]

aslında bir düğüm seçer!


1
güzel biri neden gibi sorgular anlamak için mücadele ediyordu: ".//td[contains(.//*,'something ')]" sadece 1 derinlik çalışır. Nasıl çalıştığını anladım ama değildi yukarıdakilerin nasıl çalıştığından emin olabilirsiniz. Aslında ihtiyacım olan şey ".//td[.//*[contains(.,'something ')]]"
JonnyRaa

11

Bu XPath'taki yaygın bir yanlış anlama hakkında eski bir soruya yeni bir cevap contains()...

Özet: contains()aracı , bir alt içeren , olmayan bir düğümü içerir .

Detaylı açıklama

Bu XPath genellikle yanlış yorumlanır:

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

Yanlış yorum: İçinde bir öğe içerenul öğeleri seçin . liModel

Bu yanlış çünkü

  1. contains(x,y)xbir dize olmasını bekliyor ve
  2. bir dizeye birden çok öğe dönüştürmek için XPath kuraldır bu :

    Düğüm kümesi, düğüm kümesinde, belge düzeninde ilk sırada yer alan düğümün dize değeri döndürülerek bir dizeye dönüştürülür . Düğüm kümesi boşsa, boş bir dize döndürülür.

Sağ yorumlama: o Seç ulolan unsurları ilk li çocuk vardır dize değerini içeren bir Modelalt dize.

Örnekler

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'ler

  • //ul[contains(li, 'Model')]one ulöğeyi seçer .

    Not:two ul eleman seçili olmadığından ilk dizgesel değeri liçocuğu two ulolduğu Fooiçermeyen, Modelalt dizeyi.

  • //ul[li[contains(.,'Model')]]oneve two ulöğelerini seçer .

    Not: Her iki ulöğe de seçilmiştir çünkü contains()her birine liayrı ayrı uygulanır . (Böylece, karmaşık çok öğeden dizeye dönüştürme kuralından kaçınılır.) Her iki ulöğe de lidize değeri Modelalt dizeyi içeren bir alt liöğeye sahiptir - öğenin konumu artık önemli değildir.

Ayrıca bakınız


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

-5

containsÖrneğimi buraya yapıştırın :

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

2
OP kodunda tableöğe veya EC_resultsınıf değeri yok . Bu cevap burada bir anlam ifade etmiyor ve silinmesi gerekiyor.
kjhughes
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.