Ruby:如何在哈希中为名称空间添加前缀

Ruby:如何在哈希中为名称空间添加前缀,ruby,hash,savon,Ruby,Hash,Savon,我需要找出散列的级别,并为该级别中的所有元素应用名称空间 这是一个场景: 我有一个用我的数据填充的对象 接下来,我将对象转换为散列 #convert Object to Hash def my_hash Hash[instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] }] end 最后,我想循环遍历散列,并对嵌套的散列应用不同的名称空间 不幸的是,我无法找到一个好的解决方案来直接使用sa

我需要找出散列的级别,并为该级别中的所有元素应用名称空间

这是一个场景:

我有一个用我的数据填充的对象

接下来,我将对象转换为散列

#convert Object to Hash
def my_hash
  Hash[instance_variables.map { |var| [var[1..-1].to_sym, instance_variable_get(var)] }]
end
最后,我想循环遍历散列,并对嵌套的散列应用不同的名称空间

不幸的是,我无法找到一个好的解决方案来直接使用savon gem:

soap.body = request_object.my_hash
我将检查每个元素,并尝试递归地在classify方法中找到嵌套的级别:这需要更多的魔力

def classify(o)
  case o
    when Hash
      #Need to refactor this to prefix :data NS for nested hash, overwriting the default :mes NS. 
      h = {}
      o.each {|k,v| h[k] = classify(v)}
      h                 
    else
      o.class
  end 
end
soap.body = classify(request_object.my_hash)
它应该是这样的,源哈希:

{:UserTicket=>'123',:ImpersonationUsername=>'dave',:TicketSettings=>{:ResourceId=>'abcd',:ClientIp=>'0',:Username=>'bobby'}}
输出,其中mes和数据是两个名称空间:

{'mes:UserTicket'=>'123','mes:ImpersonationUsername'=>'dave','mes:TicketSettings'=>{'data:ResourceId'=>'abcd','data:ClientIp'=>'0','data:Username'=>'bobby'}}

下面是一种方法,您可以传入与每一嵌套级别相关联的标识符列表:

def classify(o, with)
  case o
    when Hash
      h = {}
      o.each {|k,v| h[:"#{with[0]}:#{k}"] = classify(v, with[1, with.length])}
      h                 
    else
      o.class
  end 
end

hash = {:UserTicket=>'123',:ImpersonationUsername=>'dave',:TicketSettings=>{:ResourceId=>'abcd',:ClientIp=>'0',:Username=>'bobby'}}

classify(hash, [ :mes, :data ])
# => {"mes:UserTicket"=>String, "mes:ImpersonationUsername"=>String, "mes:TicketSettings"=>{"data:ResourceId"=>String, "data:ClientIp"=>String, "data:Username"=>String}}

如果您使用的是递归算法,您就有机会修改每个级别的应用范围。

谢谢,它没有显示字符串,为什么不显示实际值呢?这是您在case语句的else中使用o.class的原始值。您可以删除类并最终得到o。