Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Nokogiri with Ruby to replace values in existing xml?

I am using Ruby 1.9.3 with the lastest Nokogiri gem. I have worked out how to extract values from an xml using xpath and specifying the path(?) to the element. Here is the XML file I have:

<?xml version="1.0" encoding="utf-8"?>
<File xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Houses>
        <Ranch>
            <Roof>Black</Roof>
            <Street>Markham</Street>
            <Number>34</Number>
        </Ranch>
    </Houses>
</File>

I use this code to print a value:

doc = Nokogiri::XML(File.open ("C:\\myfile.xml"))  
puts doc.xpath("//Ranch//Street")

Which outputs:

<Street>Markham</Street>

This is all working fine but what I need is to write/replace the value. I want to use the same kind of path-style lookup to pass in a value to replace the one that is there. So I want to pass a street name to this path and overwrite the street name that is there. I've been all over the internet but can only find ways to create a new XML or insert a completely new node in the file. Is there a way to replace values by line like this? Thanks.

like image 432
user3195786 Avatar asked Apr 25 '14 14:04

user3195786


1 Answers

You want the content= method:

Set the Node’s content to a Text node containing string. The string gets XML escaped, not interpreted as markup.

Note that xpath returns a NodeSet not a single Node, so you need to use at_xpath or get the single node some other way:

doc = Nokogiri::XML(File.open ("C:\\myfile.xml"))  
node = doc.xpath("//Ranch//Street")[0] # use [0] to select the first result
node.content = "New value for this node"

puts doc # produces XML document with new value for the node
like image 96
matt Avatar answered Oct 13 '22 22:10

matt