Search code examples
ruby-on-railsxmlhashspecial-characters

'-' changed to '_' while converting xml to hash in rails


xml = "<outer-tag><inner-tag>value</inner-tag></outer-tag>"

hash = Hash.from_xml(xml) ==> this gives me the following output

{"outer_tag"=>{"inner_tag"=>"value"}}

I actually need hash = {"outer-tag"=>{"inner-tag"=>"value"}}

Is there any way to convert XML to Hash without changing "-" to "_" ?


Solution

  • Let check source code at line 164. Rails normalizes the hash keys from - to _

    So, I come up with 2 solutions:

    1. Call rails private method

      xml = "<outer-tag><inner-tag>value</inner-tag></outer-tag>"
      hash = ActiveSupport::XmlMini.parse(xml)
      result = ActiveSupport::XMLConverter.new("").send(:deep_to_h, hash)
      

    This is risky since rails may have an internal changes and we are in error-prone

    1. Convert key from _ back to -

      xml = "<outer-tag><inner-tag>value</inner-tag></outer-tag>"
      hash = Hash.from_xml(xml)
      normalize_keys = -> (params) do
        case params
          when Hash
            Hash[params.map { |k,v| [k.to_s.tr('_', '-'), normalize_keys.call(v)] } ]
          when Array
            params.map { |v| normalize_keys.call(v) }
          else
            params
        end
      end
      result = normalize_keys.call(hash)
      

    This is better, but too much longer, just my idea, welcome any comment!