Method: Hash#to_xml
- Defined in:
- activesupport/lib/active_support/core_ext/hash/conversions.rb
#to_xml(options = {}) ⇒ Object
Returns a string containing an XML representation of its receiver:
{ foo: 1, bar: 2 }.to_xml
# =>
# <?xml version="1.0" encoding="UTF-8"?>
# <hash>
# <foo type="integer">1</foo>
# <bar type="integer">2</bar>
# </hash>
To do so, the method loops over the pairs and builds nodes that depend on the values. Given a pair key
, value
:
-
If
value
is a hash there’s a recursive call withkey
as:root
. -
If
value
is an array there’s a recursive call withkey
as:root
, andkey
singularized as:children
. -
If
value
is a callable object it must expect one or two arguments. Depending on the arity, the callable is invoked with theoptions
hash as first argument withkey
as:root
, andkey
singularized as second argument. The callable can add nodes by usingoptions[:builder]
.{foo: lambda { |, key| [:builder].b(key) }}.to_xml # => "<b>foo</b>"
-
If
value
responds toto_xml
the method is invoked withkey
as:root
.class Foo def to_xml() [:builder]. 'fooing!' end end { foo: Foo.new }.to_xml(skip_instruct: true) # => # <hash> # <bar>fooing!</bar> # </hash>
-
Otherwise, a node with
key
as tag is created with a string representation ofvalue
as text node. Ifvalue
isnil
an attribute “nil” set to “true” is added. Unless the option:skip_types
exists and is true, an attribute “type” is added as well according to the following mapping:XML_TYPE_NAMES = { "Symbol" => "symbol", "Integer" => "integer", "BigDecimal" => "decimal", "Float" => "float", "TrueClass" => "boolean", "FalseClass" => "boolean", "Date" => "date", "DateTime" => "dateTime", "Time" => "dateTime" }
By default the root node is “hash”, but that’s configurable via the :root
option.
The default XML builder is a fresh instance of Builder::XmlMarkup
. You can configure your own builder with the :builder
option. The method also accepts options like :dasherize
and friends, they are forwarded to the builder.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'activesupport/lib/active_support/core_ext/hash/conversions.rb', line 74 def to_xml( = {}) require "active_support/builder" unless defined?(Builder::XmlMarkup) = .dup [:indent] ||= 2 [:root] ||= "hash" [:builder] ||= Builder::XmlMarkup.new(indent: [:indent]) builder = [:builder] builder.instruct! unless .delete(:skip_instruct) root = ActiveSupport::XmlMini.rename_key([:root].to_s, ) builder.tag!(root) do each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, ) } yield builder if block_given? end end |