HOWTO · Ruby
How to Parse XML With Ruby
Parse XML in Ruby with Nokogiri, select elements with XPath or CSS, read text and attributes, and write document changes.
On this page
Nokogiri lets a Ruby program parse XML into a document that can be queried and changed. This guide covers installation, parsing, selecting elements, reading text and attributes, and writing edits. The complete example uses Nokogiri when it is installed and Ruby’s standard REXML library as a fallback, so the same workflow can run without an external gem.
Install Nokogiri
Run gem install nokogiri in a terminal to install Nokogiri for the Ruby environment used by your application. For a project that tracks dependencies, add gem 'nokogiri' to its Gemfile and install the declared dependencies so the gem is available to the project. The Nokogiri calls described below assume that your program has loaded the gem with require 'nokogiri'.
Parse an XML Document
Nokogiri::XML(xml) parses an XML string and returns a document that Ruby code can query. To parse a file, read its contents and pass the string to the parser, as in Nokogiri::XML(File.read(path)); use a path supplied by your application. The example below prefers Nokogiri and falls back to REXML if the gem is unavailable. Both branches print the same selected values and update the document in memory. Run this example:
xml = '<catalog><book id="b1"><title>Ruby Basics</title></book><book id="b2"><title>XML Guide</title></book></catalog>'
begin
require 'nokogiri'
rescue LoadError
require 'rexml/document'
end
if defined?(Nokogiri)
doc = Nokogiri::XML(xml)
doc.xpath('//book/title').each { |title| puts title.text }
book = doc.at_xpath('//book')
puts book['id']
book.at_xpath('title').content = 'Ruby XML Basics'
puts book.at_xpath('title').text
serialized_xml = doc.to_xml
else
doc = REXML::Document.new(xml)
doc.elements.each('//book/title') { |title| puts title.text }
book = doc.elements['//book']
puts book.attributes['id']
book.elements['title'].text = 'Ruby XML Basics'
puts book.elements['title'].text
serialized_xml = doc.to_s
end
Ruby Basics
XML Guide
b1
Ruby XML Basics
The example parses the catalog string into a Nokogiri document, prints both titles, reads the first book’s id, updates its title, and serializes the edited document with to_xml. Serialization returns a string; it does not change the source file. To persist the edit, write that string to a destination your application is authorized to use, for example File.write(path, doc.to_xml), which creates or replaces the destination file.
Select Elements and Read Text
The complete example uses doc.xpath('//book/title') to select each title below a book and prints each node’s text on its own line. For a single result, doc.at_xpath('//book/title') returns the first matching node, or nil when there is no match; check that result before calling a method on it if the source may omit the element. You can also use CSS for common matches, such as doc.css('book > title') for titles that are direct children of books.
Read XML Attributes
An element’s attributes are separate from its text content. Nokogiri’s bracket access uses the attribute name without @: book['id'] reads the id value from a selected book node. In the complete example, book is the first book returned by doc.at_xpath('//book'), and its id is printed before the title is changed. The lookup returns nil when there is no matching book, and bracket access returns nil when the attribute is absent, so check both when the source may omit them.
Modify and Write an XML Document
The complete example changes the first title with book.at_xpath('title').content = 'Ruby XML Basics' and serializes the edited document into serialized_xml with doc.to_xml. Serialization returns XML as a string and leaves the input file untouched. To save the change, pass the string to File.write(path, doc.to_xml) using a destination your application is authorized to write; this creates or replaces that destination. For a node that might not exist, check the result of at_xpath before changing it.
Choose XPath or CSS Selectors
Nokogiri supports both XPath and CSS selectors. XPath is useful for expressing relationships and conditions, such as selecting a title through its parent book or locating nodes by an attribute. CSS selectors offer familiar, concise syntax for common element and attribute matches. For the catalog structure here, doc.xpath('//book/title') and doc.css('book > title') select titles that are direct children of books. Choose whichever form makes the intended relationship clearer; both return nodes that can be inspected or modified. The choice is about expressing the query, not a universal speed ranking.