You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails如何将含嵌套数组的Hash转XML且去除数组外层包裹标签

解决Ruby Hash转XML时数组标签重复嵌套的问题

问题背景

你有这样一个带嵌套数组的Hash:

hash = { Sender_Name: "Bob", Consignement: { Load_Type: "FCL", JobContainer: [ {c_number: "123"}, {c_number: 456} ] } }

使用to_xml转换后,JobContainer数组被多套了一层同名外层标签,不符合预期格式。

解决方案

要去掉这层多余的外层标签,我们可以修改ActiveSupport::XmlMini的默认处理逻辑,让数组直接生成同级的子标签,而不是被包裹。

具体做法是重写to_tag方法,调整数组的处理逻辑:

module ActiveSupport
  module XmlMini
    module_function

    def to_tag(name, value, options = {})
      if value.is_a?(Array)
        # 遍历数组,为每个元素生成对应名称的标签,跳过外层包裹
        value.map { |v| to_tag(name, v, options) }.join
      else
        attributes = options[:attributes] || {}
        if value.respond_to?(:to_xml)
          value.to_xml(options.merge(root: name))
        else
          content = encode_value(value, options)
          "<#{name}#{attributes.map { |k, v| " #{k}=\"#{v}\"" }.join}>#{content}</#{name}>"
        end
      end
    end
  end
end

之后再执行你的to_xml调用:

hash.to_xml(skip_instruct: true, skip_types: true, root: "Consolidation2")

就能得到你想要的XML结果:

<Consolidation2>
 <Sender-Name>Bob</Sender-Name>
 <Consignement>
 <Load-Type>FCL</Load-Type>
 <JobContainer>
 <c-number>123</c-number>
 </JobContainer>
 <JobContainer>
 <c-number>456</c-number>
 </JobContainer>
 </Consignement>
</Consolidation2>

这个修改的核心是:当处理数组类型的值时,不再生成一个和数组键名相同的外层标签,而是直接为数组中的每个元素生成对应键名的标签,完美解决了嵌套冗余的问题。

内容的提问来源于stack exchange,提问作者mahi-man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:17:41