【问题标题】:Psych YAML parsing including comments心理 YAML 解析,包括注释
【发布时间】:2012-07-28 21:33:55
【问题描述】:

根据http://yaml.org/spec/current.html#id2509980 YAML 文件中的 cmets 是一个表示细节,不得在序列化/表示图 (http://yaml.org/spec/current.html#representation/) 中。看起来 Psych 正在根据规范进行解析并丢失了 cmets,这意味着当文件包含 cmets 时,无法解析 YAML 文件并以完全相同的方式再次对其进行序列化。在我看来这很奇怪,因为 cmets 在此类文件中确实很重要(例如配置)。

有谁知道是否可以使用现有库解析 cmets,或者是否可以自己完成这一切?

【问题讨论】:

  • 这是一个延伸,但您可以在加载之前将其克隆到一个临时文件中,然后在序列化后合并两个文件(使用差异?)......只要整体结构相同......或者......这是一个疯狂的想法......?
  • This blog post 建议唯一保留注释的 YAML 解析器是用于 Python 的 ruamel。

标签: ruby yaml psych


【解决方案1】:

我们也可以做一些这样的事情,这将改变键值并保留 cmets。

require 'yaml'
thing = YAML.load_file('/opt/database.yml')
hostname = thing["common"]["host_name"]
appname = thing["common"]["app_name"]
motdobj = IO.readlines('/opt/database.yml')
motdobj = motdobj.map {|s| s.gsub(hostname, "mrigesh")}
motdobj = motdobj.map {|s| s.gsub(appname, "abc")}

File.open('/opt/database.yml', "w" ) do | file1 |
    file1.puts motdobj
    file1.close
end

【讨论】:

    【解决方案2】:

    您可以在发射时对较低级别的节点进行迭代,以保持 cmets。此外,您可以查看 syck 引擎是否为您提供所需的结果。

    【解决方案3】:

    我喜欢 @josh-voigts 的疯狂想法。这是一个疯狂的实现。评论几乎可以散布在任何地方,而且很有效!

    require 'tempfile'
    
    def yaml_conf_edit(fn, &block)
      conf = File.open(fn) {|f| YAML.load(f.read)}
    
      before = Tempfile.new('before')
      before.write(conf.to_yaml)
      before.close
    
      yield conf
    
      after = Tempfile.new('after')
      after.write(conf.to_yaml)
      after.close
    
      `merge #{fn} #{before.path} #{after.path}`
      before.unlink; after.unlink
    
      conf
    end
    

    您可以在以下内容中使用:

    yaml_conf_edit('conf/database.yml') do |conf| 
      conf['development']['database'] = db_timestamped
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-24
      • 2012-01-04
      • 2018-10-15
      • 2019-08-03
      • 1970-01-01
      • 2011-10-27
      • 2020-12-29
      • 2017-02-02
      相关资源
      最近更新 更多