繁体   English   中英

从JSON动态挑选字段?

[英]Dynamically picking out fields from JSON?

我正在写一些东西来填充设备数据存储库,方法是从服务器上的代理读取JSON输出。 我遇到了一个我无法解释的障碍。

当我使用nic_bonds时,我得到:

block (2 levels) in translate': undefined method `[]' for nil:NilClass (NoMethodError)

在声明slaves =的行。 当我将["#{name}"]更改为硬编码['bond0']我最终得到了我正在寻找的内容: "bond0"=>"eth2,eth3"

当我使用类似的模式时,使用["#{name}"]使用以太网端口似乎没问题。

是什么赋予了?

码:

class DeviceDataTranslator
  def initialize(device_data_collector, device_data_repo)
    @device_data_collector = device_data_collector
    @device_data_repo = device_data_repo
  end

  # translates data between tools
  def translate
    devices_input = @device_data_collector.get_devices_data
    devices_output = []

    # translate data for each node/device
    devices_input.each do |node|

      std_fields = {}
      custom_fields = {}

      # network
      interfaces = node['automatic']['network']['interfaces']
      ethernets = interfaces.select {|k, v| k.match(/^eth/)}
      ethernets.each do |name, data|
        eth_port = {}
        mac = node['automatic']['network'].keys.find {|k| k.include? "macaddress_#{name}"}
        eth_port["#{name}_mac"] = node['automatic']['network']["#{mac}"] unless !mac
        custom_fields.merge!(eth_port)
      end

      nic_bonds = interfaces.select {|k, v| k.match(/^bond/)}
      if nic_bonds
        nic_bonds.each do |name, data|
          bond = {}
          slaves = node['automatic']['ls']['bonding']["#{name}"]['slaves'].join(',')
          bond["#{name}"] = slaves
          custom_fields.merge!(bond)
        end
      end

      # combine fields & add to devices list
      device = [std_fields, custom_fields]
      devices_output.push(device)
    end

    # handoff to device data repo
    @device_data_repo.set_devices(devices_output)
  end
end

和(减少的)JSON:

    {
      "automatic": {
        "network": {
          "interfaces": {
            "bond0": {
              "type": "bond",
              "number": "0",
              "mtu": "1500"
            },
          "default_interface": "bond0",
          "default_gateway": "x.x.x.x",
          "ipaddress_lo": "127.0.0.1",
          "ipaddress6_lo": "::1",
          "macaddress_eth2": "x-x-x-x-x-x",
          "macaddress_eth3": "x-x-x-x-x-x",
          "macaddress_eth0": "x-x-x-x-x-x",
          "macaddress_eth1": "x-x-x-x-x-x",
          "macaddress_bond0": "x-x-x-x-x-x",
          "ipaddress_bond0": "x.x.x.x"
        },
        "ls": {
          "bonding": {
            "bond0": {
              "slaves": [
                "eth2",
                "eth3"
              ]
            }
          }
        }
      }
    }
  }
block (2 levels) in translate': undefined method `[]' for nil:NilClass (NoMethodError)

当您使用不存在的密钥时,请使用。

在声明slaves =的行。 当我将[“#{name}”]更改为硬编码['bond0']时,我最终得到了我正在寻找的内容:“bond0”=>“eth2,eth3”。

所以显然name不是bond0

当我使用类似的模式使用[“#{name}”]使用以太网端口似乎没问题。

是什么赋予了?

你某处有个bug。 :)我只是跑你的样品,与所提供的JSON(不得不修复} ),但它工作正常。 也许你驱逐了一些破坏你代码的坏数据? 添加这样的语句:

p name

在你的循环中,看看那里真的是什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM