在C#中合并YAML

时间:2018-11-21 12:55:31

标签: c# yaml yamldotnet

我想将两个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

2 个答案:

答案 0 :(得分:1)

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

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

  2. 尝试用第二个替换第一个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);

        }

我希望这可以为您提供帮助:)

答案 1 :(得分:1)

使用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;
}