【问题标题】:Merging YAML in C#在 C# 中合并 YAML
【发布时间】:2018-11-21 12:55:30
【问题描述】:

我想将两个 YAML 文件合并为一个,这样可以避免重复并合并属性。例如,有两个 yaml 文件,如下所示:

yaml1:

first_name: "John"
last_name: "Smith"
enabled: false
roles:
  - user

yaml2:

enabled: true
roles:
  - user
  - admin

我希望得到以下结果:

first_name: "John"
last_name: "Smith"
enabled: true
roles:
  - user
  - admin

到目前为止,我能够将 YAML 转换为 JSON 并使用 this example,但是,我想知道一种使用 C# YAML 库(如 yamldotnetSharpYaml)的方法。

【问题讨论】:

    标签: c# yaml yamldotnet


    【解决方案1】:

    我已经使用 Yamldotnet 实现了它,然后使用了以下算法:

    1. 使用第一个 yaml 作为基础

    2. 尝试用第二个 yaml 覆盖第一个 yaml

      2.1 如果是新字段,添加它

      2.2 如果字段存在且不是集合,则覆盖它

      2.3 如果字段存在且为集合,则合并集合

      2.3.1 如果新值不是集合,则将其添加到集合中

      2.3.2 如果新值是一个集合,则将每个不重复的元素添加到集合中。出于这个原因,我使用了HashSet,这是一个不允许重复项的集合。

    代码:

    static void Main(string[] args)
            {
    
                var deserializer = new DeserializerBuilder()
                   .WithNamingConvention(new CamelCaseNamingConvention())
                   .Build();
    
                var object1 = deserializer.Deserialize<Dictionary<string,object>>(@"---
    first_name: ""John""
    last_name: ""Smith""
    enabled: false
    roles:
        - user
    ...");
    
                var object2 = deserializer.Deserialize<Dictionary<string, object>>(@"---
    enabled: true
    roles:
      - user
      - admin
    ...");
                foreach (var tuple in object2)
                {
                    if (!object1.ContainsKey(tuple.Key))
                    {
                        object1.Add(tuple.Key, tuple.Value);
                        continue;
                    }
    
                    var oldValue = object1[tuple.Key];
                    if (!(oldValue is ICollection))
                    {
                        object1[tuple.Key] = tuple.Value;
                        continue;
                    }
    
    
                    //Merge collection
                    var mergeCollection = new HashSet<object>(oldValue as IEnumerable<object>);
                    if (!(tuple.Value is ICollection))
                        mergeCollection.Add(tuple.Value);
                    else
                    {
                        foreach (var item in tuple.Value as IEnumerable)
                        {
                            mergeCollection.Add(item);
                        }
                    }
    
                    object1[tuple.Key] = mergeCollection;                                                             
    
                }
    
                var result = new SerializerBuilder().Build().Serialize(object1);
    
            }
    

    希望对你有帮助:)

    【讨论】:

      【解决方案2】:

      使用YamlDotNet,如果文档具有其部分未使用的唯一类型,则此技巧可能会有所帮助:

      using YamlDotNet.Serialization;
      using YamlDotNet.Serialization.ObjectFactories;
      
      public Document Load(string[] contents) {
          var document = new Document();
                  
          var factory = new DefaultObjectFactory();
          var deserializer = new DeserializerBuilder()
              .WithObjectFactory(type => type == typeof(Document) ? document : factory.Create(type))
              .Build();
      
          foreach (var content in contents) {
              deserializer.Deserialize<Document>(content);
          }
      
          return document;
      }
      

      【讨论】:

        猜你喜欢
        • 2010-10-23
        • 2018-04-20
        • 1970-01-01
        • 1970-01-01
        • 2018-05-05
        • 2021-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多