class EbayTrader::XMLBuilder

Attributes

context[R]
depth[R]
tab_width[R]
xml[R]

Public Class Methods

new(args = {}) click to toggle source
# File lib/ebay_trader/xml_builder.rb, line 8
def initialize(args = {})
  @xml = ''
  @depth = 0
  @tab_width = (args[:tab_width] || 0).to_i
end

Public Instance Methods

method_missing(method_name, *args, &block) click to toggle source

Catch-all method to avoid having to create individual methods for each XML tag name.

# File lib/ebay_trader/xml_builder.rb, line 15
def method_missing(method_name, *args, &block)
  if @context && @context.respond_to?(method_name)
    @context.send(method_name, *args, &block)
  else
    node(method_name, args, &block)
  end
end
respond_to_missing?(method_name, include_private = false) click to toggle source

Only respond to method names with only numbers and letters. Do not respond to names with underscores.

Calls superclass method
# File lib/ebay_trader/xml_builder.rb, line 25
def respond_to_missing?(method_name, include_private = false)
  super || method_name.to_s =~ /^[a-z0-9]+$/i
end
root(name, *args, &block) click to toggle source

Begin creating an XML string by specifying the root node. This also sets the context scope, allowing methods and variables outside the block to be accessed. @param [String] name the name of the root node element. @param [Array] args the data for this element. @param [Block] block an optional block of sub-elements to be nested

within the root node.
# File lib/ebay_trader/xml_builder.rb, line 36
def root(name, *args, &block)
  set_context(&block)
  node(name, args, &block)
end

Private Instance Methods

format_node_attributes(options) click to toggle source

Convert the given Hash of options into a string of XML element attributes.

# File lib/ebay_trader/xml_builder.rb, line 104
def format_node_attributes(options)
  options.collect { |key, value|
    value = value.to_s.gsub('"', '\"')
    " #{key}=\"#{value}\""
  }.join('')
end
get_node_attributes(args) click to toggle source

Return the first Hash in the list of arguments to node as this defines the attributes for the XML node. @return [Hash] the hash of attributes for this node.

# File lib/ebay_trader/xml_builder.rb, line 74
def get_node_attributes(args)
  args.detect { |arg| arg.is_a? Hash } || {}
end
get_node_content(args) click to toggle source

Return the node content as a String, unless a block is given. @return [String] the node data.

# File lib/ebay_trader/xml_builder.rb, line 81
def get_node_content(args)
  return nil if block_given?
  content = nil
  args.each do |arg|
    case arg
      when Hash
        next
      when Time
        # eBay official TimeStamp format YYYY-MM-DDTHH:MM:SS.SSSZ
        content = arg.strftime('%Y-%m-%dT%H:%M:%S.%Z')
      when DateTime
        content = arg.strftime('%Y-%m-%dT%H:%M:%S.%Z')
        break
      else
        content = arg.to_s
        break
    end
  end
  content
end
indent_new_line() click to toggle source

Add a new line to the XML and indent with the appropriate number of spaces.

# File lib/ebay_trader/xml_builder.rb, line 112
def indent_new_line
  tab_width > 0 ? ("\n" + (' ' * tab_width * depth)) : ''
end
node(name, args, &block) click to toggle source

Create an XML node @param [String|Symbol] name the name of the XML element (ul, li, strong, etc…) @param [Array] args Can contain a String of text or a Hash of attributes @param [Block] block An optional block which will further nest XML

# File lib/ebay_trader/xml_builder.rb, line 54
def node(name, args, &block)
  content = get_node_content(args)
  options = format_node_attributes(get_node_attributes(args))

  @_segments ||= []
  @_segments << "#{indent_new_line}<#{name}#{options}>#{content}"
  if block_given?
    @depth += 1
    instance_eval(&block)
    @depth -= 1
    @_segments << indent_new_line
  end
  @_segments << "</#{name}>"
  @xml = @_segments.join('').strip
end
set_context(&block) click to toggle source

@see github.com/sparklemotion/nokogiri/blob/master/lib/nokogiri/xml/builder.rb

# File lib/ebay_trader/xml_builder.rb, line 45
def set_context(&block)
  @context = block_given? ? eval('self', block.binding) : nil
  @context = nil if @context.is_a?(XMLBuilder)
end