2016-08-14 33 views
10

Z pomocą this SO question Mam XPath prawie pracy:Xpath: wybierz div, który zawiera klasę i którego specyficzny element podrzędny zawiera tekst

//div[contains(@class, 'measure-tab') and contains(., 'someText')] 

Jednak to dostaje dwa divs: w jednym jest to dziecko td że ma someText, drugi to dziecko span.

Jak mogę zawęzić to do tego z span?

<div class="measure-tab"> 
    <!-- table html omitted --> 
    <td> someText</td> 
</div> 

<div class="measure-tab"> <-- I want to select this div (and use contains @class) 
    <div> 
    <span> someText</span> <-- that contains a deeply nested span with this text 
    </div> 
</div> 
+1

Musisz wpisać xml wejściowe co najmniej część tego, co chcesz napisać xpath? – SomeDude

+0

Masz na myśli '... i zawiera (span, 'someText')]'? –

+0

Tak właśnie myślałem, ale otrzymałem "brak pasujących węzłów" w walidatorze FirePath – Andrejs

Odpowiedz

14

Aby znaleźć div pewnej klasy, która zawiera spanat any depth zawierające określony tekst, spróbuj:

//div[contains(@class, 'measure-tab') and contains(.//span, 'someText')] 

Powiedział, że to rozwiązanie wygląda bardzo kruche. Jeśli tabela zawiera tekst o nazwie span z tekstem, którego szukasz, dopasowana zostanie również tabela div zawierająca tabelę. Proponuję znaleźć bardziej skuteczny sposób filtrowania elementów. Na przykład za pomocą identyfikatorów lub struktury dokumentu najwyższego poziomu.

+1

Screen-scraping jest zawsze z natury bardzo delikatny. –

2

Można użyć XPath:

//div[@class="measure-tab" and .//span[contains(., "someText")]]

Wejście:

<root> 
<div class="measure-tab"> 
    <td> someText</td> 
</div> 
<div class="measure-tab"> 
    <div> 
    <div2> 
     <span>someText2</span> 
    </div2> 
    </div> 
</div> 
</root> 

wyjściowa:

Element='<div class="measure-tab"> 
    <div> 
    <div2> 
     <span>someText2</span> 
    </div2> 
    </div> 
</div>' 
+0

To by wybrało rozpiętość, a nie div. –

+0

Myślałem, że OP chciał 'span' – SomeDude

+1

Starałem się, aby było to tak wyraźne, jak to tylko możliwe z <- comment :) – Andrejs

3

można zmienić drugi warunek, aby sprawdzić tylko element rozpiętości:

...and contains(div/span, 'someText')] 

Jeśli zakres nie zawsze jest wewnątrz innego div można również użyć

...and contains(.//span, 'someText')] 

To wyszukuje przęsła w dowolnym miejscu wewnątrz div.

+0

Zaakceptowanie odpowiedzi nwellnhofa, gdy otrzymał ją jako pierwszą, ale +1 za alternatywę. Twoje zdrowie. – Andrejs

2

Można użyć ancestor. Uważam, że jest to łatwiejsze do odczytania, ponieważ element, który właśnie wybierasz, znajduje się na końcu ścieżki.

//span[contains(text(),'someText')]/ancestor::div[contains(@class, 'measure-tab')]