2016-10-04 1 views
0

У меня есть следующий XML:Как получить весь текст без текста с конкретными тегами с помощью Nokogiri?

<w:body> 
    <w:p w14:paraId="15812FB6" w14:textId="27A946A1" w:rsidR="001665B3" w:rsidRDefault="00771852"> 
    <w:r> 
     <w:t xml:space="preserve">I am writing this </w:t> 
    </w:r> 
    <w:ins w:author="Mitchell Gould" w:date="2016-10-04T17:24:00Z" w:id="0"> 
     <w:r w:rsidR="00A1573E"> 
     <w:t>text to look</w:t> 
     </w:r> 
    </w:ins> 
    <w:del w:author="Mitchell Gould" w:date="2016-10-04T17:24:00Z" w:id="1"> 
     <w:r w:rsidDel="00A1573E"> 
     <w:delText>to test</w:delText> 
     </w:r> 
    </w:del> 
... 

Я знаю, что я получаю получить весь текст с помощью:

only_text_array = @file.search('//text()') 

однако, я на самом деле хочу два текстовых наборов:

  • One который содержит весь текст, кроме текста из элементов <w:del>...</w:del>.
  • Другое, которое содержит весь текст, кроме текста из <w:ins>...</w:ins> элементов.

Как это сделать?

ответ

1

Вы можете попробовать использовать следующее XPath:

//text()[not(ancestor::w:del or ancestor::w:ins)] 

xpatheval demo

Это XPath возвращает все текстовые узлы, где ни один из предка не w:del или w:ins

+0

Именно то, что я искал. Спасибо har07. – chell

0

Я бы сделайте примерно следующее:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p class="ignore">foobar</p> 
    <p>Keep this</p> 
    <p class="ignore2">foobar2</p> 
    </body> 
</html> 
EOT 

text1, text2 = %w[.ignore .ignore2].map do |s| 
    tmp_doc = doc.dup 
    tmp_doc.search(s).remove 
    tmp_doc.text.strip 
end 

text1 # => "Keep this\n foobar2" 
text2 # => "foobar\n Keep this" 

Он выполняет итерацию по списку селекторов вещей, которые не нужны, dup s документ, а затем удаляет нежелательные узлы и возвращает текст документа после некоторой очистки.

dup выполняет глубокую копию по умолчанию, поэтому удаление узлов не повлияет на doc.

Смежные вопросы