使用ruby代码从YAML文件中获取所有值

时间:2017-05-02 07:30:14

标签: ruby yaml

我想从这个YAML文件中获取所有值:

Test_server :
  processing_url : "https://test.net/process/"

  xml_files: 
      file: "test1.xml"
      config:
          terminal_name: "test1_gate"
          token: "a86713d51072a01c74b9fbec8c3297be5841546f"
          api_login: "a04d98f30d88b1311c061500fd5a29064f218460"
          api_password: "QUX2NwrZrrx5hQQbb3EmTLXznbUoOpKUY4Pr3iV8"

      file: "test2.xml"
      config:
          terminal_name: "test2_gate"
          token: "8edb910368993e0fb8dea4de37abafd41fbbd697"
          api_login: "1ffd8d50589ee248d00884876b328c2ae268a813"
          api_password: "e4ca6e468332d0ebb47aca4fc0640aa61ebda691"

      file: "test3.xml"
      config:
          terminal_name: "test3_gate"
          token: "abfbed2c74c88bfdd99320511001d850b1915d66"
          api_login: "e2ed5327d59f059ce19d6585eced53873685230e"
          api_password: "AvvYMLgnfJdXSFO7NgVWuAvxRbKcEEI4QT65EGaz"

我使用此代码获取值:

[21] pry(main)> config = YAML.load_file("config/test_config.yml")
=> {"STG_PSP"=>
  {"processing_url"=>"https://test.net/process/",
   "xml_files"=>
    {"file"=>"test3.xml",
     "config"=>
      {"terminal_name"=>"test3_gate",
       "token"=>"abfbed2c74c88bfdd99320511001d850b1915d66",
       "api_login"=>"e2ed5327d59f059ce19d6585eced53873685230e",
       "api_password"=>"AvvYMLgnfJdXSFO7NgVWuAvxRbKcEEI4QT65EGaz"}}}}
[22] pry(main)> 

你可以看到我总是得到最后一个值。如何使用Ruby从YAML文件中获取所有值?

1 个答案:

答案 0 :(得分:1)

你拥有的是一个哈希,你需要的是一个列表。

您的yaml文件相当于一个哈希值,该哈希值会覆盖密钥fileconfig的值3次。

您最好的做法是在irb中创建此类列表,然后将其另存为yaml。

require "yaml"

file1 = {
  file: "test1.xml",
  config: {
      terminal_name: "test1_gate",
      token: "a86713d51072a01c74b9fbec8c3297be5841546f",
      api_login: "a04d98f30d88b1311c061500fd5a29064f218460",
      api_password: "QUX2NwrZrrx5hQQbb3EmTLXznbUoOpKUY4Pr3iV8"
  }
}

file2 = {  
  file: "test2.xml",
  config: {
    terminal_name: "test2_gate",
    token: "8edb910368993e0fb8dea4de37abafd41fbbd697",
    api_login: "1ffd8d50589ee248d00884876b328c2ae268a813",
    api_password: "e4ca6e468332d0ebb47aca4fc0640aa61ebda691"
  }
}

file3 = {
  file: "test3.xml",
  config: {
    terminal_name: "test3_gate",
    token: "abfbed2c74c88bfdd99320511001d850b1915d66",
    api_login: "e2ed5327d59f059ce19d6585eced53873685230e",
    api_password: "AvvYMLgnfJdXSFO7NgVWuAvxRbKcEEI4QT65EGaz"
  }
}

files = [file1, file2, file3]
puts files.to_yaml

输出是这样的:

---
- :file: test1.xml
  :config:
    :terminal_name: test1_gate
    :token: a86713d51072a01c74b9fbec8c3297be5841546f
    :api_login: a04d98f30d88b1311c061500fd5a29064f218460
    :api_password: QUX2NwrZrrx5hQQbb3EmTLXznbUoOpKUY4Pr3iV8
- :file: test2.xml
  :config:
    :terminal_name: test2_gate
    :token: 8edb910368993e0fb8dea4de37abafd41fbbd697
    :api_login: 1ffd8d50589ee248d00884876b328c2ae268a813
    :api_password: e4ca6e468332d0ebb47aca4fc0640aa61ebda691
- :file: test3.xml
  :config:
    :terminal_name: test3_gate
    :token: abfbed2c74c88bfdd99320511001d850b1915d66
    :api_login: e2ed5327d59f059ce19d6585eced53873685230e
    :api_password: AvvYMLgnfJdXSFO7NgVWuAvxRbKcEEI4QT65EGaz
在yaml文件的初始化中

-表示这是一个列表项。 你可能有字符串作为键,我的代码使用符号。

如何提取所有值?

如果要从该yaml文件中提取所有值,我认为最简单的方法是更改​​yaml文件。你需要一个小样本的yaml文件,这是完美的。确认它是完美的,然后只更改不匹配的行。

假设您需要仅将file: "更改为- file: " 在这种情况下,逐行检查并更改与file: "

匹配的行

这样的事情:

# corrects one line in yaml file
# this is just an idea, you need to implement it yourself
def correct_line(line)
  # file_regex - regex to match 'file: "', test using rubular.com
  if line =~ file_regex
    # it's a line that starts with `file: "`
    # change it to start with `- file: "`
    return corrected
  else
    # just return line which is not modified 
    line
  end
end

yaml = YAML.load_file('test.yaml')
original_lines = yaml.split(/\n+/)
corrected_lines = original_lines.map { |line| correct_line(line) }
File.write('/path/to/file', corrected_lines.join("\n"))

如果您了解TDD和rspec,则correct_line是使用TDD编写的理想选择。

你也许可以以某种方式拦截ruby代码,它将新的键/值对添加到哈希并更改它以将您的条目添加到列表中,然后将其保存为yaml。我不知道该怎么做。

这可能更简单。我会谷歌how to intercept hash code which adds key value pair in ruby或类似的东西。如果找不到,请提出新问题并链接到此答案。