Skip to content

Instantly share code, notes, and snippets.

@darrenclark
Created December 1, 2011 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenclark/1414672 to your computer and use it in GitHub Desktop.
Save darrenclark/1414672 to your computer and use it in GitHub Desktop.
A fairly easy to use class for parsing XML elements (from Nokogiri) into value objects
require 'rubygems'
require 'nokogiri'
class XMLRecord
class << self
def tag_handlers
@tag_handlers ||= []
end
end
def self.handle(tag_name=/.*/, namespace_prefix=/.*/, &block)
self.tag_handlers << {:name => Regexp.new(tag_name), :ns => Regexp.new(namespace_prefix), :block => block}
end
def initialize(xml)
xml.children.each do |child|
self.class.tag_handlers.each do |handler|
prefix = child.namespace.nil? == true ? "" : (child.namespace.prefix || "")
if child.name =~ handler[:name] && prefix =~ handler[:ns]
self.instance_exec child, &handler[:block]
end
end
end
end
end
if $0 == __FILE__
class Example < XMLRecord
def strings
@strings ||= []
end
attr_accessor :number
handle 'string' do |child|
self.strings << child.inner_text
end
handle 'number' do |child|
self.number = child.inner_text.to_i
end
end
xml_string = "<file>
<strings>
<number>1</number>
<string>One</string>
<string>Two</string>
<string>Three</string>
</strings>
<strings>
<number>2</number>
<string>Four</string>
<string>Five</string>
</strings>
</file>"
xml_doc = Nokogiri::XML(xml_string)
examples = xml_doc.xpath('//file/strings').map { |child| Example.new(child) }
examples.each { |ex| puts ex.number.to_s + ". " + ex.strings.join(', ') }
end
__END__
$ ruby xmlrecord.rb
1. One, Two, Three
2. Four, Five
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment