以下是如何测试您的 YAML 是否有效,以及我如何生成 YAML 以在文件或其他地方使用:
require 'yaml'
str = <<EOT
DATA_SVC_GEN_CONF_ATTR:
-
-
-
name: validationCodeNum
value: 1
-
name: validationCodeSymbol
value: "val1"
-
name: sql
value: Test
-
name: sqlByGridArea
value: Test1
EOT
data = YAML.load(str)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [[[{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]]]}
如果 YAML 无法解析数据,它会抱怨。如果可以并且数据不是您所期望的,那么输出可以帮助您诊断问题。
当我想创建一个 YAML 文件,尤其是一个复杂的文件时,我从实际的数据结构开始,让 YAML 生成它的序列化版本:
data = {
'DATA_SVC_GEN_CONF_ATTR' =>
[
[
[
{
'name' => 'validationCodeNum',
'value' => 1
},
{
'name' => 'validationCodeSymbol',
'value' => 'val1'
},
{
'name' => 'sql',
'value' => 'Test'
},
{
'name' => 'sqlByGridArea',
'value' => 'Test1'
}
]
]
]
}
puts data.to_yaml
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: sql
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
继续...要更改 YAML 文件中的元素,您可以将文件视为文本,逐行读取,通过 slurping 读取,或者让 YAML 打开它并更改生成的对象,然后使用 YAML重写它。
如果您确定数据适合内存并且可以轻松找到要更改的部分,则可以使用 Slurping 文件。逐行阅读通常可以更轻松地找到特定文本,因为您处理的是单个行,而不是整个文件。
我认为使用 YAML 是最简单的,因为它可以减少写得不好的正则表达式做错事的变化。
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- - - name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
假设data 是磁盘上YAML 文件的内容,它会被使用YAML.load_file 加载和解析。在这个例子中,我作为一个字符串加载,所以我必须使用load:
object = YAML.load(data)
现在对数据进行了解析,因此可以轻松地对其进行操作:
object['DATA_SVC_GEN_CONF_ATTR'].first.first[2]['name'] = "Select * from table"
那么就可以写回了:
puts object.to_yaml # => nil
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: Select * from table
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
如果这是一个关键任务(生产)文件,您需要执行适当的重命名、写入、删除步骤来保护数据以防出现错误,但这就是要点。
不过,您的数据结构非常有问题。您使用嵌套数组数组数组只是为了保存您的哈希,这不是很常见或容易理解。相反,它应该简化为单个数组:
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
object = YAML.load(data)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]}
object['DATA_SVC_GEN_CONF_ATTR'][2]['name'] = "Select * from table"