我有一个像这样的 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
它有效,但我想保留我原来的 anchor 名称,否则它会变得不可读。有什么想法吗?
最佳答案
您可以使用 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
的返回值,该结构很容易理解,您可以编写一些代码,如顶部的答案。
关于ruby - 当我用 Ruby 解析 YAML 时,它改变了我的 anchor 名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28544637/