Sreeraj Chundayil
Sreeraj Chundayil

Reputation: 5859

Why my Nokogiri selector not working?

This is my first attempt using Nokogiri, but it doesn't work and I don't understand why:

This is the XML:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
   </book>
</catalog>

I'm using this code:

require 'nokogiri'

f = File.open("test.xml")
doc = Nokogiri::XML(f)
nodes = doc.xpath("title")
nodes.each do |node|
    print node.text
end

I am getting the nodes as a nil class.

Upvotes: 0

Views: 407

Answers (2)

the Tin Man
the Tin Man

Reputation: 160571

I'd write the code like:

require 'nokogiri'

doc = Nokogiri::XML(File.read("test.xml"))
nodes = doc.search("title")
puts nodes.map(&:text)

Back to the problem. You used:

nodes = doc.xpath("title")

which is forcing Nokogiri to interpret your selector as XPath, and will look for an immediate ancestor of <catalog> named <title>. That doesn't exist. Instead, you'd need to use //title if you want to search throughout the document for any <title> tags.

Or, instead of forcing xpath, if you'd used search instead, Nokogiri would have decided you meant it to use a CSS selector title, and it would have worked correctly, since, in CSS, title would search the entire document.

I recommend using CSS over XPath as it's more readable. XPath is extremely powerful but it also quickly gathers a lot of visual noise as the selector becomes more powerful.

Upvotes: 0

Ursus
Ursus

Reputation: 30071

To select nodes matching the selector try:

nodes = doc.xpath("//title")

Upvotes: 1

Related Questions