123456789_123456789_123456789_123456789_123456789_

Module: ActiveSupport::XmlMini

Relationships & Source Files
Namespace Children
Modules:
Defined in: activesupport/lib/active_support/xml_mini.rb

Overview

XmlMini

To use the much faster libxml parser:

gem "libxml-ruby"
XmlMini.backend = 'LibXML'

Constant Summary

  • DEFAULT_ENCODINGS =
    # File 'activesupport/lib/active_support/xml_mini.rb', line 34
    {
      "binary" => "base64"
    }
  • FORMATTING =
    # File 'activesupport/lib/active_support/xml_mini.rb', line 56
    {
      "symbol"   => Proc.new { |symbol| symbol.to_s },
      "date"     => Proc.new { |date| date.to_fs(:db) },
      "dateTime" => Proc.new { |time| time.xmlschema },
      "duration" => Proc.new { |duration| duration.iso8601 },
      "binary"   => Proc.new { |binary| ::Base64.encode64(binary) },
      "yaml"     => Proc.new { |yaml| yaml.to_yaml }
    }
  • PARSING =
    # File 'activesupport/lib/active_support/xml_mini.rb', line 67
    {
      "symbol"       => Proc.new { |symbol|  symbol.to_s.to_sym },
      "date"         => Proc.new { |date|    ::Date.parse(date) },
      "datetime"     => Proc.new { |time|    Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc },
      "duration"     => Proc.new { |duration| Duration.parse(duration) },
      "integer"      => Proc.new { |integer| integer.to_i },
      "float"        => Proc.new { |float|   float.to_f },
      "decimal"      => Proc.new do |number|
        if String === number
          number.to_d
        else
          BigDecimal(number)
        end
      end,
      "boolean"      => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) },
      "string"       => Proc.new { |string|  string.to_s },
      "yaml"         => Proc.new { |yaml|    YAML.load(yaml) rescue yaml },
      "base64Binary" => Proc.new { |bin|     ::Base64.decode64(bin) },
      "hexBinary"    => Proc.new { |bin|     _parse_hex_binary(bin) },
      "binary"       => Proc.new { |bin, entity| _parse_binary(bin, entity) },
      "file"         => Proc.new { |file, entity| _parse_file(file, entity) }
    }
  • TYPE_NAMES =
    # File 'activesupport/lib/active_support/xml_mini.rb', line 39
    {
      "Symbol"     => "symbol",
      "Integer"    => "integer",
      "BigDecimal" => "decimal",
      "Float"      => "float",
      "TrueClass"  => "boolean",
      "FalseClass" => "boolean",
      "Date"       => "date",
      "DateTime"   => "dateTime",
      "Time"       => "dateTime",
      "ActiveSupport::Duration" => "duration",
      "Array"      => "array",
      "Hash"       => "hash"
    }

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#backend (rw)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 101

def backend
  current_thread_backend || @backend
end

#backend=(name) (rw)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 105

def backend=(name)
  backend = name && cast_backend_name_to_module(name)
  self.current_thread_backend = backend if current_thread_backend
  @backend = backend
end

#current_thread_backend (rw, private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 192

def current_thread_backend
  IsolatedExecutionState[:xml_mini_backend]
end

#current_thread_backend=(name) (rw, private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 196

def current_thread_backend=(name)
  IsolatedExecutionState[:xml_mini_backend] = name && cast_backend_name_to_module(name)
end

#depth (rw)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 96

attr_accessor :depth

#parse (readonly)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 99

delegate :parse, to: :backend

Instance Method Details

#_dasherize(key) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 163

def _dasherize(key)
  # $2 must be a non-greedy regex for this to work
  left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1, 3]
  "#{left}#{middle.tr('_ ', '--')}#{right}"
end

#_parse_binary(bin, entity) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 169

def _parse_binary(bin, entity)
  case entity["encoding"]
  when "base64"
    ::Base64.decode64(bin)
  when "hex", "hexBinary"
    _parse_hex_binary(bin)
  else
    bin
  end
end

#_parse_file(file, entity) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 180

def _parse_file(file, entity)
  f = StringIO.new(::Base64.decode64(file))
  f.extend(FileLike)
  f.original_filename = entity["name"]
  f.content_type = entity["content_type"]
  f
end

#_parse_hex_binary(bin) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 188

def _parse_hex_binary(bin)
  [bin].pack("H*")
end

#cast_backend_name_to_module(name) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 200

def cast_backend_name_to_module(name)
  if name.is_a?(Module)
    name
  else
    require "active_support/xml_mini/#{name.downcase}"
    ActiveSupport.const_get("XmlMini_#{name}")
  end
end

#rename_key(key, options = {})

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 152

def rename_key(key, options = {})
  camelize  = options[:camelize]
  dasherize = !options.has_key?(:dasherize) || options[:dasherize]
  if camelize
    key = true == camelize ? key.camelize : key.camelize(camelize)
  end
  key = _dasherize(key) if dasherize
  key
end

#to_tag(key, value, options)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 119

def to_tag(key, value, options)
  type_name = options.delete(:type)
  merged_options = options.merge(root: key, skip_instruct: true)

  if value.is_a?(::Method) || value.is_a?(::Proc)
    if value.arity == 1
      value.call(merged_options)
    else
      value.call(merged_options, key.to_s.singularize)
    end
  elsif value.respond_to?(:to_xml)
    value.to_xml(merged_options)
  else
    type_name ||= TYPE_NAMES[value.class.name]
    type_name ||= value.class.name if value && !value.respond_to?(:to_str)
    type_name   = type_name.to_s   if type_name
    type_name   = "dateTime" if type_name == "datetime"

    key = rename_key(key.to_s, options)

    attributes = options[:skip_types] || type_name.nil? ? {} : { type: type_name }
    attributes[:nil] = true if value.nil?

    encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name]
    attributes[:encoding] = encoding if encoding

    formatted_value = FORMATTING[type_name] && !value.nil? ?
      FORMATTING[type_name].call(value) : value

    options[:builder].tag!(key, formatted_value, attributes)
  end
end

#with_backend(name)

[ GitHub ]

  
# File 'activesupport/lib/active_support/xml_mini.rb', line 111

def with_backend(name)
  old_backend = current_thread_backend
  self.current_thread_backend = name && cast_backend_name_to_module(name)
  yield
ensure
  self.current_thread_backend = old_backend
end