2012-05-29 3 views
17

У меня есть некоторые HTML, который выглядит как:Получить текст непосредственно внутри тега в Nokogiri

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

У меня уже есть все мои HTML загружается в переменную под названием record. Мне нужно разобрать год, то есть 2009 год, если он существует.

Как я могу получить текст внутри тега dt, но не текст внутри тега a? Я использовал record.search("dt").inner_text, и это дает мне все.

Это тривиальный вопрос, но мне не удалось это понять.

+1

Отметим также, что на самом деле существует два текстовых узлов внутри этого 'dt' (если не вам проанализировал HTML, используя опцию «noblanks»): первый текстовый узел «\ n» перед «», а второй текстовый узел «\ n (2009) \ n» «после него». – Phrogz

ответ

16

Чтобы получить все прямые детей с текстом, но не какие-либо дополнительными подгруппами детей, вы можете использовать XPath следующим образом:

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

Или, если вы хотите использовать поиск:

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

Вышеуказанные методы дают вам узел NodeSet узлов ['XML :: Text'] (http://nokogiri.org/Nokogiri/XML/Text.html); вы можете использовать 'at_xpath' (или просто' at'), чтобы получить единственный результат, а затем вызвать методы '.content' или' .text' на этом узле, чтобы получить текст в виде строки из него. – Phrogz

5

dt элемента имеет двое детей, так что вы можете получить доступ к этому:

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

Использование XPath т o выберите именно то, что вы хотите (как это предложил @Casper), это правильный ответ.

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

Вот альтернатива, весело ответ :)

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

Видел в действии:

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