Patches Are... Wait For It... Just Data
James Snell: This is clearly better, IMHO, than the line-based diff, but still requires that the client and server both be able to do identical Atom-to-JSON serializations.
Why? My daughter is studying Algebra II right now, and evaluating f(g(x))
, and if she can master such concepts, so can we:
require 'rexml/document' require 'json' doc = REXML::Document.new(open(ARGV[0]).read) SINGULAR = {'authors'=>'author'} JSON.parse(open(ARGV[1]).read).each {|rule| # map json path to xpath path=rule['path'] path=path[0..-3]+["@#{path.last}"] if path[-2] == 'attributes' path.map! {|item| SINGULAR[item] || item} name = path.pop if rule['action'] == 'create' path=path.join('/') path.gsub!(/\/(\d+)/) {"[#{$1.to_i+1}]"} # apply the action value = rule['value'] case rule['action'] when 'edit' if path.index('@') doc.elements[path].normalized=REXML::Text.normalize(value) else doc.elements[path].text = value end when 'create' if name[0] == ?@ name = '@xml:lang' if name=='@lang' doc.elements[path].attributes[name[1..-1]] = value elsif value == [] doc.elements[path].add_element(name) elsif value != {} doc.elements[path].add_element(name).add_text(value) end end } puts doc
Note: the above is just barely enough to handle the input data and patch in James’ example, but with a few more test cases, this could quickly become full function.