Merging a document into another

13 views
Skip to first unread message

cv

unread,
Mar 21, 2014, 5:09:53 PM3/21/14
to nokogi...@googlegroups.com
Greetings,

I'm new to Ruby and Nokogiri, so please forgive the cluelessness. 

I'm trying to put together some code that "merges" two documents. The idea is basically to add any nodes that are not present, and if a matching node exists, but it differs, correct it.

I'm using traverse, replace and add_child, and not exactly getting the expected results. Before I keep trying to make it work, I'd like to know if I'm totally off. Here's the code:

require 'nokogiri'
require 'pp'

class Nokogiri::XML::Node
  # Determine if two nodes are equal
  # (borrowed from nokogiri-diff)
  def is_equal(node)
    if (self.class == node.class)
      case node
      when Nokogiri::XML::Attr
        (self.name == node.name && self.value == node.value)
      when Nokogiri::XML::Element, Nokogiri::XML::DTD
        self.name == node.name
      when Nokogiri::XML::Text, Nokogiri::XML::Comment
        self.text == node.text
      when Nokogiri::XML::ProcessingInstruction
        (self.name == node.name && self.content = self.content)
      else
        false
      end
    else
      false
    end
  end
end

class Nokogiri::XML::Document
  # Merge XML document into another
  # 
  # Paramters:
  # patch - XML (patch) document
  # 
  # Returns:
  # String with merged XML
  #
  def merge(patch) 
    
    patch.root.traverse do |node|
      path = node.path
      if ( mynode = self.at(path) )
        puts "Found node at #{path} containing: #{node}"
        if ( !node.is_equal(mynode) )
          puts "Node #{pp node} is not equal to #{mynode}"
          mynode.replace(node)
        else
          puts "Node #{pp node} is equal to #{mynode}"
        end
      else
        puts "Node not found at #{path}"
        ppath = node.parent.path
        puts "Parent's path is #{ppath}"
        if ( mypar = self.at(ppath) )
          mypar.add_child(node)
        else
          puts "Parent not found at #{ppath}"
        end
      end
    end
    return self.to_xml        
  end

end


dir = '/home/test/'
f1 = dir + 'config.xml'
f2 = dir + 'patch.xml'

xml1 = Nokogiri::XML(File.open(f1))
xml2 = Nokogiri::XML(File.open(f2))

puts xml1.merge(xml2)



----


Any pointers would be very much appreciated.

cv

cv

unread,
Mar 24, 2014, 4:59:37 PM3/24/14
to nokogi...@googlegroups.com

Or is there a much simpler way to do this with Nokogiri Builder?
Reply all
Reply to author
Forward
0 new messages