ruby - 当我用 Ruby 解析 YAML 时,它改变了我的 anchor 名称

标签 ruby anchor yaml

我有一个像这样的 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/

相关文章:

ruby-on-rails - Arel + Rails 4.2 导致问题(绑定(bind)丢失)

ruby - 集成 watir-webdriver 和 browsermob/proxy 以及 webdriver-user-agent

java - 使用 htmlunit 单击 javascript anchor 似乎不起作用

javascript - Mozilla 在 WebForm_DoPostBackWithOptions JavaScript 函数中获取奇怪的值

html - 在没有 anchor 标签的情况下链接到网页上的任意内容

Azure DevOps Pipeline - YAML 格式错误?

Perl:命令行覆盖配置文件设置?

ruby-on-rails - Rails 图像文档