Слияние YAML в C # - PullRequest
       30

Слияние YAML в C #

0 голосов
/ 21 ноября 2018

Я хочу объединить два файла 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 и использовать этот пример , однако я хотел узнать способ использования библиотек C # YAML (например, yamldotnet * 1015).* и SharpYaml ).

1 Ответ

0 голосов
/ 21 ноября 2018

Я добился этого с помощью 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);

        }

Надеюсь, это поможет вам:)

...