2011-10-14 15 views
11

Chcę zlokalizować element na stronie internetowej za pomocą tekstu.
wiem, że jest to nazwa metody zawiera się to zrobić, na przykład:Selen: Jak zlokalizować węzeł przy użyciu dokładnego dopasowania tekstu.

tr[contains(.,'hello')]/td 

Ale problemem jest to, czy mam dwa elementy wymienić cześć i hello1 wtedy ta funkcja nie działa prawidłowo.

Czy istnieje inna metoda, np. Zawierająca dokładne dopasowanie pasujące do lokalizacji elementów?

+0

Co masz na myśli mówiąc "nie działa prawidłowo"? Jakie jest nieoczekiwane zachowanie? –

+0

jeśli mamy dwa elementy z tekstem hello i hello1, a kiedy używamy zawiera (., 'Hello'), ta metoda zawsze będzie wyglądała na cześć. Problem, jeśli te elementy znajdują się w tabeli, a hello1 jest pierwszym elementem, a hello jest drugim, a gdy użyjemy hello, to zawsze wskaże hello1, ponieważ jest to pierwszy element i zawiera hello, ale chcemy przeszukać to, dlaczego potrzebuję dokładnego dopasuj metodę –

Odpowiedz

1

Twój problem polega na tym, że przeszukujesz tekst w tr (co i tak nie jest poprawne), a to powoduje problem z funkcją contains, która nie może zaakceptować listy tekstu. Spróbuj użyć tej ścieżki lokalizacji. Powinien odzyskać to, co chcesz.

//tr/td[contains(./text(),"hello")] 

Ta ścieżka lokalizacji wyszuka zestaw węzłów, w których należy dokonać iteracji w celu pobrania tekstu. Można spróbować dołączyć

/text() 

ale spowoduje to (przynajmniej w moim teście) wyniku, który jest ciąg, który jest połączeniem wszystkich dopasowanych strun.

+0

Nie ma nic złego w używaniu 'zawiera (., cokolwiek) "na elemencie TR, chociaż prawdopodobnie nie jest to tym, czego naprawdę chce Abhinav. '.' jest skrótem dla' self :: node() ', a nie dla' descendant-or-self :: text() ', więc powoduje, że TR i wszystkie jego potomki są konwertowane na ciągi, łączone i porównywane. , zamiast szukać pojedynczego węzła tekstowego, który pasuje. –

+0

@RossPatterson Faktem jest, że jeśli robisz dobry kod, nie ma tekstu pod tr, ale tylko jeden (lub więcej) td. Mając to na uwadze, powiedziałem o "co i tak nie jest poprawne". –

16
tr[.//text()='hello']/td 

będzie wybrać wszystkie elementy podrzędne td tr wszystkich elementów mających dziecko z dokładnie „cześć” w nim. Takie XPath wciąż wydaje mi się dziwne.

wierzę, że to sprawia, że ​​więcej sensu:

tr/td[./text()='hello'] 

ponieważ wybiera tylko td, który zawiera tekst.

to pomaga?

3

Wszystko zależy od tego, co twój HTML rzeczywiście zawiera, ale twój tr[contains(.,'hello')]/td selektor XPath oznacza „pierwszą komórkę z pierwszego rzędu, który zawiera ciąg«Hello»w dowolnym miejscu to” (lub, bardziej precyzyjnie, "pierwszy element TD w elemencie TR, który zawiera ciąg "hello" w dowolnym miejscu w nim ", ponieważ Selenium nie ma pojęcia, co naprawdę robią elementy). Właśnie dlatego otrzymuje zły wynik, gdy wiersze zawierają "hello" i "hello1" - oba zawierają "hello".

Selektor tr[. ='hello']/td byłby bardziej dokładne, ale to trochę nietypowe (bo elementy HTML TR nie mają zawierać tekst - tekst ma być w TH lub elementów TD obrębie TR), a to prawdopodobnie wygrał nie działa (ponieważ tekst w dowolnych innych komórkach przerwałby porównanie). Prawdopodobnie chcesztr[td[.='hello']]/td, co oznacza "pierwszy element TD zawarty w elemencie TR, który zawiera element TD, który ma ciąg" hello "jako pełny tekst".

+0

Właśnie nauczyłem się sztuczki. = 'Text' dzięki temu wpisowi. Dzięki @Ross Patterson! W tym przypadku możesz dokładnie dopasować DOWOLNE td na stronie za pomocą //td[.='hello '], aby znaleźć DOWOLNĄ komórkę TD zawierającą DOKŁADNIE "cześć". Tr prawdopodobnie nie jest konieczne, chyba że chcesz upewnić się, że td jest wewnątrz tr. –

Powiązane problemy