2012-05-29 11 views
17

Mam niektóre HTML, który wygląda tak:Get tekst bezpośrednio wewnątrz znacznika w Nokogiri

<dt> 
    <a href="#">Hello</a> 
    (2009) 
</dt> 

mam już całe HTML załadowanej do zmiennej o nazwie record. Muszę przeanalizować rok, czyli rok 2009, jeśli istnieje.

Jak mogę uzyskać tekst wewnątrz znacznika dt, ale nie tekst wewnątrz znacznika a? Użyłem record.search("dt").inner_text i to daje mi wszystko.

To banalne pytanie, ale nie udało mi się tego rozgryźć.

+1

Należy również zauważyć, że nie są w rzeczywistości dwoma węzłami tekst wewnątrz tego 'dt' (chyba, że przeanalizował HTML za pomocą opcji 'noblanks'): pierwszy węzeł tekstowy to' '\ n" 'przed' ', a drugim węzłem tekstowym jest' "\ n (2009) \ n" "po nim. – Phrogz

Odpowiedz

16

Aby uzyskać wszystkie bezpośrednie dzieci z tekstu, ale bez żadnych dodatkowych sub-dzieci, można użyć XPath tak:

doc.xpath('//dt/text()') 

Lub jeśli chcesz korzystać z wyszukiwania:

doc.search('dt').xpath('text()') 
+3

Powyższe metody dają NodeSet węzłów ['XML :: Text'] (http://nokogiri.org/Nokogiri/XML/Text.html); możesz użyć 'at_xpath' (lub po prostu' at'), aby uzyskać pojedynczy wynik, a następnie wywołać metody '.content' lub' .text' w tym węźle, aby pobrać tekst z niego. – Phrogz

5

Element dt ma dwoje dzieci, więc można uzyskać do niego dostęp przez:

doc.search("dt").children.last.text 
7

Korzystanie XPath t o wybierz dokładnie to, co chcesz (zgodnie z sugestią @Casper) jest właściwą odpowiedzią.

def own_text(node) 
    # Find the content of all child text nodes and join them together 
    node.xpath('text()').text 
end 

Oto alternatywa, odpowiedź zabawa :)

def own_text(node) 
    node.clone(1).tap{ |copy| copy.element_children.remove }.text 
end 

widziany w akcji:

require 'nokogiri' 
root = Nokogiri.XML('<r>hi <a>BOO</a> there</r>').root 
puts root.text  #=> hi BOO there 
puts own_text(root) #=> hi there 
Powiązane problemy