我想从这个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文件中获取所有值?
答案 0 :(得分:1)
你拥有的是一个哈希,你需要的是一个列表。
您的yaml文件相当于一个哈希值,该哈希值会覆盖密钥file
和config
的值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
或类似的东西。如果找不到,请提出新问题并链接到此答案。