# Print - and strip text between tags using Nokogiri

**URL:** <https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898>\
**Category:** ruby-talk\
**Created:** [15 December 2012 23:10 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898 "2012-12-15T23:10:41Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [15 December 2012 23:10 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/1 "2012-12-15T23:10:41Z")

</div>

I'm a Ruby Newbie trying to write a program to process thousands of HTML  
files, extracting pertinent text and inserting it into a MySQL database.  
Ruby seems ideally suited to the task in general, and I've already used  
Nokogiri to extract comment text. What I need to do next is to print -  
and then ultimately delete or strip - the text between "pre" tags.

Picture some html like this:

\<html\>  
\<head\>  
\<title\>My Title\</title\>  
\</head\>  
\<body\>  
\<h1\>My Heading\</h1\>  
\<strong\>From:\</strong\>Me\<br\>  
\<strong\>Date:\</strong\> Wed Dec 05 2012 - 18:17:49 EST  
\<!-- body="start" --\>  
\<p\>  
text line 1  
\<br\>  
text line 2  
\<br\>  
text line 3  
\<br\>  
\<p\>\<pre\>  
very important text  
more important text  
would you believe even more important text?  
\</pre\>  
\<p\>\<!-- body="end" --\>  
\</body\>  
\</html\>

I basically need to do 2 things: 1) to print only the text between the 2  
"pre" tags, and then 2) to print all of the non-tagged text between the  
"body" comments - minus the text between the "pre" tags. I've been  
messing with this for a couple of hours - unsuccessfully - but I'm still  
convinced that this is the right tool for the job.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [15 December 2012 23:28 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/2 "2012-12-15T23:28:30Z")

</div>

If you need to do more HTML and XML manipulation, learning XPath is a  
good investment! You can look here for a start:  
[http://www.w3schools.com/Xpath/default.asp](http://www.w3schools.com/Xpath/default.asp)

\_One\_ way to achieve what you want:

require 'nokogiri'

text = \<\<HTML  
\<html\>  
\<head\>  
\<title\>My Title\</title\>  
\</head\>  
\<body\>  
\<h1\>My Heading\</h1\>  
\<strong\>From:\</strong\>Me\<br\>  
\<strong\>Date:\</strong\> Wed Dec 05 2012 - 18:17:49 EST  
\<!-- body="start" --\>  
\<p\>  
text line 1  
\<br\>  
text line 2  
\<br\>  
text line 3  
\<br\>  
\<p\>\<pre\>  
very important text  
more important text  
would you believe even more important text?  
\</pre\>  
\<p\>\<!-- body="end" --\>  
\</body\>  
\</html\>  
HTML

dom = Nokogiri.HTML(text)

puts dom.xpath('/html/body//pre/text()').map(&:to\_s)

puts '---'

puts dom.xpath('/html/body//text()[not(ancestor::pre)]').map(&:to\_s)

You can also process nodes individually if you replace ".map..." with  
".each" and a block which receives the node and does something with  
it.

Kind regards

robert

> **···**
>
> On Sun, Dec 16, 2012 at 12:10 AM, Paul Mena \<lists@ruby-forum.com\> wrote:
> 
> > I'm a Ruby Newbie trying to write a program to process thousands of HTML  
> > files, extracting pertinent text and inserting it into a MySQL database.  
> > Ruby seems ideally suited to the task in general, and I've already used  
> > Nokogiri to extract comment text. What I need to do next is to print -  
> > and then ultimately delete or strip - the text between "pre" tags.
> > 
> > Picture some html like this:
> > 
> > \<html\>  
> > \<head\>  
> > \<title\>My Title\</title\>  
> > \</head\>  
> > \<body\>  
> > \<h1\>My Heading\</h1\>  
> > \<strong\>From:\</strong\>Me\<br\>  
> > \<strong\>Date:\</strong\> Wed Dec 05 2012 - 18:17:49 EST  
> > \<!-- body="start" --\>  
> > \<p\>  
> > text line 1  
> > \<br\>  
> > text line 2  
> > \<br\>  
> > text line 3  
> > \<br\>  
> > \<p\>\<pre\>  
> > very important text  
> > more important text  
> > would you believe even more important text?  
> > \</pre\>  
> > \<p\>\<!-- body="end" --\>  
> > \</body\>  
> > \</html\>
> > 
> > I basically need to do 2 things: 1) to print only the text between the 2  
> > "pre" tags, and then 2) to print all of the non-tagged text between the  
> > "body" comments - minus the text between the "pre" tags. I've been  
> > messing with this for a couple of hours - unsuccessfully - but I'm still  
> > convinced that this is the right tool for the job.
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 02:23 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/3 "2012-12-16T02:23:16Z")

</div>

Thank you for the swift reply! I tried running the above against my  
"test.html" snippet and ended up getting the following:

pablo@cochituate=\> ./extract\_text.rb ./test.html

> **···**
>
> ---  
> ./test.html
> 
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 10:37 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/4 "2012-12-16T10:37:25Z")

</div>

There should be a way to match the text of the first comment, but I  
couldn't get this to work:

comment()[text()='body="start"']

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 10:52 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/5 "2012-12-16T10:52:17Z")

</div>

This ugly xpath will select the comment based on its text:

my\_xpath = %Q{/html/body/comment()[. =' body="start"  
']/following-sibling::\*[not(self::pre)]}

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 16:11 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/6 "2012-12-16T16:11:50Z")

</div>

I want the thank everyone for their quick replies and helpful  
suggestions. I realized that I should probably be using the real - and  
admittedly poorly-formed - HTML for this question and not the test HTML  
I've tried to concoct for this example. The real HTML was generated by  
the Hypermail program, basically converting an email from mbox form to  
HTML. Here is one such file:

\<html\>  
\<head\>  
\<title\>haiku\_archive: watching the news\</title\>  
\<meta name="Author" content="Paul David Mena ([pauldavidmena@gmail.com](mailto:pauldavidmena@gmail.com))"\>  
\<meta name="Subject" content="watching the news"\>  
\</head\>  
\<body bgcolor="#FFFFFF" text="#000000"\>  
\<h1\>watching the news\</h1\>  
\<strong\>From:\</strong\> Paul David Mena (\<a  
[href="mailto:pauldavidmena@gmail.com](mailto:href=%22mailto:pauldavidmena@gmail.com)?Subject=Re:%20watching%20the%20news&In-Reply-To=&lt;CAOJ9yjPRsvJ8%2BtMKjCeUnKGKcuHGQ3kuakE%2BL%2BHS1gWCMEh8jQ@mail.gmail.com&gt;"\>\<em\>[pauldavidmena@gmail.com](mailto:pauldavidmena@gmail.com)\</em\>\</a\>)\<br\>  
\<strong\>Date:\</strong\> Fri Dec 14 2012 - 18:51:14 EST  
\<p\>  
\<hr noshade\>\<p\>  
\<!-- body="start" --\>  
\<p\>  
watching the news  
\<br\>  
I feel guilty  
\<br\>  
for being alive  
\<br\>  
\<p\>\<pre\>

> **···**
>
> --  
> Paul David Mena  
> --------------------  
> \<a  
> [href="mailto:pauldavidmena@gmail.com](mailto:href=%22mailto:pauldavidmena@gmail.com)?Subject=Re:%20watching%20the%20news&In-Reply-To=&lt;CAOJ9yjPRsvJ8%2BtMKjCeUnKGKcuHGQ3kuakE%2BL%2BHS1gWCMEh8jQ@mail.gmail.com&gt;"\>[pauldavidmena@gmail.com](mailto:pauldavidmena@gmail.com)\</a\>  
> \</pre\>  
> \<p\>\<!-- body="end" --\>  
> \</body\>  
> \</html\>
> 
> My ultimate goal is to extract all of the comment text between \<!--  
> body="start" --\> and \<!-- body="end" --\> but \*not\* what is between the  
> two "pre" tags. So far I've been able to extract all of the comment  
> text but not exclude the "pre" text, using the following code:
> 
> #!/usr/bin/env ruby
> 
> require "rubygems"  
> require "nokogiri"
> 
> class PlainTextExtractor \< Nokogiri::XML::SAX::Document
> 
> &nbsp;&nbsp;attr\_reader :plaintext
> 
> &nbsp;&nbsp;# Initialize the state of interest variable with false  
> &nbsp;&nbsp;def initialize  
> &nbsp;&nbsp;&nbsp;&nbsp;@interesting = false  
> &nbsp;&nbsp;&nbsp;&nbsp;@plaintext = ""  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;# This method is called whenever a comment occurs and  
> &nbsp;&nbsp;# the comments text is passed in as string.  
> &nbsp;&nbsp;def comment(string)  
> &nbsp;&nbsp;&nbsp;&nbsp;case string.strip # strip leading and trailing whitespaces  
> &nbsp;&nbsp;&nbsp;&nbsp;when /^body="start"/ # match starting comment  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@interesting = true  
> &nbsp;&nbsp;&nbsp;&nbsp;when /^body="end"/  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@interesting = false # match closing comment  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;# This callback method is called with any string between  
> &nbsp;&nbsp;# a tag.  
> &nbsp;&nbsp;def characters(string)  
> &nbsp;&nbsp;&nbsp;&nbsp;@plaintext \<\< string if @interesting  
> &nbsp;&nbsp;end  
> end
> 
> # write to the screen  
> pte = PlainTextExtractor.new  
> parser = Nokogiri::HTML::SAX::Parser.new(pte)  
> parser.parse\_file ARGV[0]  
> # puts pte.plaintext
> 
> # write to a file  
> begin  
> &nbsp;&nbsp;file = File.open("snippet.txt", "w")  
> &nbsp;&nbsp;file.write pte.plaintext  
> rescue IOError =\> e  
> &nbsp;&nbsp;#some error occur, dir not writable etc.  
> ensure  
> &nbsp;&nbsp;file.close unless file == nil  
> end
> 
> # get the date written  
> fname = ARGV[0]  
> start\_column = 3  
> end\_column = 5
> 
> target\_range = (start\_column-1)..(end\_column-1)
> 
> IO.foreach(fname) do |line|  
> &nbsp;&nbsp;if line.match(/\<strong\>Date:\<\/strong\>/)  
> &nbsp;&nbsp;&nbsp;&nbsp;pieces = line.split(" ")  
> &nbsp;&nbsp;&nbsp;&nbsp;puts pieces[target\_range].join("-")  
> &nbsp;&nbsp;end  
> end
> 
> # remove blank lines from file  
> fh = File.open('snippet.txt')  
> while( !fh.eof)  
> &nbsp;&nbsp;&nbsp;&nbsp;line = fh.readline.chomp  
> &nbsp;&nbsp;&nbsp;&nbsp;# remove leading and trailing blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.strip!  
> &nbsp;&nbsp;&nbsp;&nbsp;# skip empty lines  
> &nbsp;&nbsp;&nbsp;&nbsp;next if line == ''  
> &nbsp;&nbsp;&nbsp;&nbsp;# convert tab chars to blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.gsub!(/\t/,' ')  
> &nbsp;&nbsp;&nbsp;&nbsp;# substitute a single blank for a sequence of blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.squeeze!(' ')  
> &nbsp;&nbsp;&nbsp;&nbsp;# add code to process line if needed  
> &nbsp;&nbsp;&nbsp;&nbsp;puts line  
> end  
> fh.close  
> exit(0)
> 
> The output is as follows:
> 
> pablo@cochituate=\> ./extract\_haiku.rb  
> /export/www/html/haikupoet/archive/0925.html  
> watching the news  
> I feel guilty  
> for being alive  
> --  
> Paul David Mena  
> --------------------  
> [pauldavidmena@gmail.com](mailto:pauldavidmena@gmail.com)
> 
> Basically I want to omit the signature (everything below the "--",  
> inclusive), which is wrapped in the "pre" tags.
> 
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 21:17 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/7 "2012-12-16T21:17:43Z")

</div>

require "nokogiri"

class PlainTextExtractor \< Nokogiri::XML::SAX::Document  
&nbsp;&nbsp;attr\_reader :plaintext  
&nbsp;&nbsp;# Initialize the state of interest variable with false  
&nbsp;&nbsp;def initialize  
&nbsp;&nbsp;&nbsp;&nbsp;@interesting = false  
&nbsp;&nbsp;&nbsp;&nbsp;@pre = false  
&nbsp;&nbsp;&nbsp;&nbsp;@plaintext = ""  
&nbsp;&nbsp;end

&nbsp;&nbsp;def start\_element(name, attrs = [])  
&nbsp;&nbsp;&nbsp;&nbsp;if name == "pre"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@pre = true  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;# This method is called whenever a comment occurs and  
&nbsp;&nbsp;# the comments text is passed in as string.  
&nbsp;&nbsp;def comment(string)  
&nbsp;&nbsp;&nbsp;&nbsp;case string.strip # strip leading and trailing whitespaces  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /^body="start"/ # match starting comment  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@interesting = true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when /^body="end"/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@interesting = false # match closing comment  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;# This callback method is called with any string between  
&nbsp;&nbsp;# a tag.  
&nbsp;&nbsp;def characters(string)  
&nbsp;&nbsp;&nbsp;&nbsp;if @interesting and not @pre  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@plaintext \<\< string  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end  
end

pte = PlainTextExtractor.new  
parser = Nokogiri::HTML::SAX::Parser.new(pte)  
parser.parse\_file ARGV[0]

p pte.plaintext

--output:--  
"\n\nwatching the news\n\nI feel guilty\n\nfor being alive\n\n"

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 23:57 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/8 "2012-12-16T23:57:12Z")

</div>

7stud - that's perfect. Thank you so much!

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Tamara\_Temple1](https://avatars.discourse-cdn.com/v4/letter/t/5f9b8f/32.png) [@Tamara\_Temple1](https://rubytalk.org/u/Tamara_Temple1)\
**Post date:** [16 December 2012 03:21 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/9 "2012-12-16T03:21:25Z")

</div>

You passed in the file name string to nokugiri, not the contents.

> **···**
>
> On Sat, Dec 15, 2012 at 8:23 PM, Paul Mena \<lists@ruby-forum.com\> wrote:
> 
> > Thank you for the swift reply! I tried running the above against my  
> > "test.html" snippet and ended up getting the following:
> > 
> > pablo@cochituate=\> ./extract\_text.rb ./test.html  
> > ---  
> > ./test.html
> > 
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [16 December 2012 10:18 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/10 "2012-12-16T10:18:42Z")

</div>

Robert Klemme wrote in post #1089225:

> puts dom.xpath('/html/body//pre/text()').map(&:to\_s)

Calling map() is redundant because puts calls to\_s on its arguments.

> 2) to print all of the non-tagged text between the  
> "body" comments

Your html doesn't even test your requirements because there is no text  
after the body="end' comment. And there is no non-tagged text:

require 'nokogiri'

html = \<\<HTML  
\<html\>  
\<head\>  
\<title\>My Title\</title\>  
\</head\>  
\<body\>  
\<h1\>My Heading\</h1\>  
\<strong\>From:\</strong\>Me\<br\>  
\<strong\>Date:\</strong\> Wed Dec 05 2012 - 18:17:49 EST  
\<!-- body="start" --\>  
\<p\>  
text line 1  
\<br\>  
text line 2  
\<br\>  
text line 3  
\<br\>  
\<p\>\<pre\>  
very important text  
more important text  
would you believe even more important text?  
\</pre\>  
\<p\>\<!-- body="end" --\>  
\<p\>  
text line 4  
\<br\>  
text line 5  
\</body\>  
\</html\>  
HTML

doc = Nokogiri.HTML(html)

my\_xpath = "/html/body/comment()[1]/following-sibling::\*"

doc.xpath(my\_xpath).each do |node|  
&nbsp;&nbsp;puts node.name  
&nbsp;&nbsp;puts node.text  
&nbsp;&nbsp;puts '\*' \* 20  
end

--output:--  
p

text line 1

text line 2

text line 3

> **···**
>
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> p
> 
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> pre
> 
> very important text  
> more important text  
> would you believe even more important text?  
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> p
> 
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
> p
> 
> text line 4
> 
> text line 5  
> \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
> 
> --output:--  
> text line 1  
> text line 2  
> text line 3
> 
> doc = Nokogiri.HTML(html)
> 
> my\_xpath =  
> "/html/body/comment()[1]/following-sibling::\*[not(self::pre)]"
> 
> catch :found\_ending\_text do  
> &nbsp;&nbsp;doc.xpath(my\_xpath).each do |node|  
> &nbsp;&nbsp;&nbsp;&nbsp;node.children.each do |child|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text = child.text  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw :found\_ending\_text if text.include? %q{body}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;next if text.empty?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts text.strip  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end  
> end
> 
> --output:--  
> text line 1  
> text line 2  
> text line 3
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [17 December 2012 01:01 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/11 "2012-12-17T01:01:18Z")

</div>

Paul Mena wrote in post #1089283:

> # remove blank lines from file  
> fh = File.open('snippet.txt')  
> while( !fh.eof)  
> &nbsp;&nbsp;&nbsp;&nbsp;line = fh.readline.chomp  
> &nbsp;&nbsp;&nbsp;&nbsp;# remove leading and trailing blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.strip!  
> &nbsp;&nbsp;&nbsp;&nbsp;# skip empty lines  
> &nbsp;&nbsp;&nbsp;&nbsp;next if line == ''  
> &nbsp;&nbsp;&nbsp;&nbsp;# convert tab chars to blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.gsub!(/\t/,' ')  
> &nbsp;&nbsp;&nbsp;&nbsp;# substitute a single blank for a sequence of blanks  
> &nbsp;&nbsp;&nbsp;&nbsp;line.squeeze!(' ')  
> &nbsp;&nbsp;&nbsp;&nbsp;# add code to process line if needed  
> &nbsp;&nbsp;&nbsp;&nbsp;puts line  
> end  
> fh.close  
> exit(0)

I forgot to mention. There are several ways to read line by line from a  
file, but your loop is particularly ugly. If you use my favorite:

IO.foreach(fname) do |line|  
&nbsp;&nbsp;line = line.chomp  
&nbsp;&nbsp;...  
&nbsp;&nbsp;..  
end

The added benefit is that the file is automatically closed when the  
block exits.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [17 December 2012 06:12 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/12 "2012-12-17T06:12:41Z")

</div>

7stud -- wrote in post #1089314:

> I forgot to mention. There are several ways to read line by line from a  
> file,

Here are some others:

f = File.new(fname)

f.each do |line|  
&nbsp;&nbsp;line = line.chomp

end

f.close

> **···**
>
> ====
> 
> File.open(fname) do |f|  
> &nbsp;&nbsp;while line = f.gets #gets() returns nil at eof  
> &nbsp;&nbsp;...  
> &nbsp;&nbsp;end  
> end #file is automatically closed here
> 
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [17 December 2012 08:11 UTC](https://rubytalk.org/t/print-and-strip-text-between-tags-using-nokogiri/66898/13 "2012-12-17T08:11:41Z")

</div>

> Robert Klemme wrote in post #1089225:
> 
> > puts dom.xpath('/html/body//pre/text()').map(&:to\_s)
> 
> Calling map() is redundant because puts calls to\_s on its arguments.

Right, thanks for the reminder! That was an artifact of IRB testing. 🙂

> > 2) to print all of the non-tagged text between the  
> > "body" comments
> 
> Your html doesn't even test your requirements because there is no text  
> after the body="end' comment. And there is no non-tagged text:

I overlooked the comment thing.

#!/usr/bin/ruby

require 'nokogiri'  
# require 'irb'

text = \<\<HTML  
\<html\>  
\<head\>  
\<title\>My Title\</title\>  
\</head\>  
\<body\>  
\<h1\>My Heading\</h1\>  
\<strong\>From:\</strong\>Me\<br\>  
\<strong\>Date:\</strong\> Wed Dec 05 2012 - 18:17:49 EST  
\<!-- body="start" --\>  
\<p\>  
text line 1  
\<br\>  
text line 2  
\<br\>  
text line 3  
\<br\>  
\<p\>\<pre\>  
very important text  
more important text  
would you believe even more important text?  
\</pre\>  
\<p\>\<!-- body="end" --\>  
not to print  
\</body\>  
\</html\>  
HTML

dom = Nokogiri.HTML(text)

puts dom.xpath('/html/body//pre/text()')

puts '---'

puts dom.xpath('//text()[contains(preceding::comment(),"start") and  
contains(following::comment(),"end") and not(ancestor::pre)]')

Kind regards

robert

> **···**
>
> On Sun, Dec 16, 2012 at 11:18 AM, 7stud -- \<lists@ruby-forum.com\> wrote:
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)
