Получение узла YAMLDotNet/SharpYAML с использованием пути к строке (например, "category.object.parameter")

Во всех других библиотеках YAML, которые я использовал, можно получить узел, просто введя путь к нему в виде строки в функции get. Есть ли такая функция в YAMLDotNet?

2 ответа

Решение

Это не похоже на это, но есть открытый запрос функции. Вы можете следить за этим, если вам интересно: https://github.com/aaubry/YamlDotNet/issues/333

Я решил прочитать файл yaml, а затем просто преобразовать его в json, вот код для этого, если кому-то интересно:

    public JObject root = null;
    public void ReadLanguage()
    {
        try
        {
            // Reads file contents into FileStream
            FileStream stream = File.OpenRead(languagesPath + filename + ".yml");

            // Converts the FileStream into a YAML Dictionary object
            var deserializer = new DeserializerBuilder().Build();
            var yamlObject = deserializer.Deserialize(new StreamReader(stream));

            // Converts the YAML Dictionary into JSON String
            var serializer = new SerializerBuilder()
                .JsonCompatible()
                .Build();
            string jsonString = serializer.Serialize(yamlObject);

            root = JObject.Parse(jsonString);
            plugin.Info("Successfully loaded language file.");
        }
        catch (Exception e)
        {
            if (e is DirectoryNotFoundException)
            {
                plugin.Error("Language directory not found.");
            }
            else if (e is UnauthorizedAccessException)
            {
                plugin.Error("Language file access denied.");
            }
            else if (e is FileNotFoundException)
            {
                plugin.Error("'" + filename + ".yml' was not found.");
            }
            else if (e is JsonReaderException || e is YamlException)
            {
                plugin.Error("'" + filename + ".yml' formatting error.");
            }
            plugin.Error("Error reading language file '" + filename + ".yml'. Deactivating plugin...");
            plugin.Debug(e.ToString());
            plugin.Disable();
        }
    }

Я не рекомендую делать это, если вы можете избежать этого, мне пришлось использовать yaml, и я бы сошел с ума без строковых путей в коде.

Я нанёс ему удар. Этот код, вероятно, нуждается в небольшой очистке и дополнительной проверке ошибок, но, похоже, он работает. Общая идея заключается в том, что вы идете по пути, например/someNode/anotherNode и он вернет YamlNode в этом месте:

using System;
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;

namespace YamlTransform
{
    public static class Extensions
    {
        public static YamlNode XPath(this YamlDocument doc, string path)
        {
            if (!(doc.RootNode is YamlMappingNode mappingNode)) // Cannot search non mapping nodes
            {
                return null;
            }

            var sections = new Queue<string>(path.Split('/', StringSplitOptions.RemoveEmptyEntries));
            while (sections.Count > 1)
            {
                string nextSection = sections.Dequeue();
                var key = new YamlScalarNode(nextSection);

                if (mappingNode == null || !mappingNode.Children.ContainsKey(key))
                {
                    return null; // Path does not exist
                }

                mappingNode = mappingNode[key] as YamlMappingNode;
            }

            return mappingNode?[new YamlScalarNode(sections.Dequeue())];
        }
    }
}
Другие вопросы по тегам