Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS 

A Fast Ruby XML Builder

Here's something I wrote this evening. It's a simple and fast XML builder. Some benchmark I ran show it to be about 4 times faster than <a>Builder. Usage example:

   1  
   2  items = ['abc', 'def', 'ghi']
   3  xml = XML.new do
   4    instruct!
   5    reality(:time => Time.now) do
   6    event do
   7      type 1
   8      path "/sharon"
   9      value "abcdefg"
  10    end
  11    list.each {|i| item i}
  12  end
  13  puts xml.to_s


The XML class:

   1  
   2  class XML
   3    # blank slate
   4    instance_methods.each { |m| undef_method m unless (m =~ /^__|instance_eval$/)}
   5    
   6    # Each item in @doc is an array containing three values: type, value, attributes
   7    
   8    def initialize(&block)
   9      @doc = []
  10      instance_eval(&block)
  11    end
  12    
  13    def method_missing(tag, *args, &block)
  14      value = block ? nil : args.pop
  15      attributes = args.pop
  16      @__to_s = nil # invalidate to_s cache
  17      if value
  18        @doc << [:open, tag, attributes] << [:value, value] << [:close, tag]
  19      else
  20        @doc << [:open, tag, attributes]
  21        instance_eval(&block)
  22        @doc << [:close, tag]
  23      end
  24    end
  25    
  26    def instruct!(atts = nil)
  27      @doc << [:instruct, atts || {:version => "1.0", :encoding => "UTF-8"}]
  28    end
  29  
  30    def to_s
  31      @__to_s ||= @doc.map{|i| _fmt_part i}.join
  32    end
  33    
  34    alias_method :inspect, :to_s
  35    
  36    def _fmt_part(part)
  37      case part[0]
  38      when :instruct
  39        "<?xml #{_fmt_atts(part[1])}?>"
  40      when :open
  41        part[2] ? "<#{part[1]} #{_fmt_atts(part[2])}>" :
  42          "<#{part[1]}>"
  43      when :close
  44        "</#{part[1]}>"
  45      when :value
  46        part[1].to_s
  47      end
  48    end
  49  
  50    def _fmt_atts(atts)
  51      atts.inject([]) {|m, i| m << "#{i[0]}=#{i[1].to_s.inspect}"}.join(' ')
  52    end
  53  end
« Newer Snippets
Older Snippets »
Showing 1-1 of 1 total  RSS