我有一个像这样的YAML文件:
- axis: &kadeployversion
type: user-defined
name: kadeployversion
values:
- kadeploy3
- kadeploy3-dev
我用Ruby编辑了这个文件:
require 'yaml'
jjb = YAML.load_file(fileToParse)
jjb[0]['type']='test'
File.open(fileToParse, 'w+'){
|f| f.write jjb.to_yaml
}
但是当我读到我的新文件时,我有这个:
- axis: &12345678
type: test
name: kadeployversion
values:
- kadeploy3
- kadeploy3-dev
它有效,但我想保留原来的主播名称,否则它将变得不可读。有什么想法吗?
答案 0 :(得分:3)
您可以使用mid-level parsing API:
来实现这一目标stream = Psych.parse_stream(yaml)
document = stream.children[0]
mapping = document.children[0]
index = mapping.children.index {|x|
x.is_a?(Psych::Nodes::Scalar) && x.value == 'type'
}
mapping.children[index + 1].value = "new type"
puts stream.to_yaml
使用标准加载/转储是不可能的,因为标签信息会丢失。再次转储已解析的YAML时发生的情况等同于:
a = [3]
puts({"version"=>a, "axis"=>a}.to_yaml)
###
---
version: &1
- 3
axis: *1
应用任意ID来标记对象。
但你不是运气不好!通过下降到心理mid-level parsing API,此数据存在,您可以使用它。
yaml = <<EOS
version: &kadeployversion
- 3
axis: *kadeployversion
type: something
EOS
puts Psych.parse_stream(yaml).to_yaml
###
version: &kadeployversion
- 3
axis: *kadeployversion
type: something
parse_stream
返回一个AST而不是普通的ruby对象,所以现在的诀窍就是更新那个AST,这比你一直尝试的更难和可能更脆弱。如果你pp
parse_stream
的返回值,希望结构很容易遵循,你可以在顶部编写一些代码,如答案。