Ищу руководство по чтению.yaml файлов с помощью C#
Два месяца спустя: файл YAML (Eve Online blueprint.yaml), который я попытался проанализировать, изменил огромную сделку, которая также значительно упростила анализ с использованием deserializer. Если кто-то (по какой-либо причине) хотел бы увидеть код, он обновляется на https://github.com/hkraal/ParseYaml
Основываясь на комментарии Стива Уэллена, я изменил код, чтобы делать меньше вещей одновременно. Это не имело значения в самой ошибке. Я создал другой проект (Example1) в своем решении, чтобы протестировать фактический пример, найденный на aaubry.net, на который я ссылался ранее.
Это дало мне ту же ошибку при использовании "динамического" ключа, что привело к моему текущему выводу: есть разница между:
items:
- part_no: A4786
а также
items:
part_no: A4786
Первый используется в примере, который я (ошибочно) предположил, что могу применить к моему файлу.yaml, который использует второй синтаксис.
Теперь осталось выяснить, как я могу получить "дочерние" элементы моего ключа с помощью синтаксиса, используемого в моем файле yaml...
Поскольку C# используется на работе, я начал думать о хорошем проекте, чтобы узнать о различных аспектах языка, имея прямую цель работать над этим. Тем не менее, я ударил свою первую стену довольно рано в моем проекте, разбирающем файл Yaml. Моя цель - создать список объектов YamlBlueprint, как определено в YamlBlueprint.cs, но я даже не до конца файла Yaml.
Я установил тестовый пример на github, который демонстрирует проблему: https://github.com/hkraal/ParseYaml
Пример на http://www.aaubry.net/page/YamlDotNet-Documentation-Loading-a-YAML-stream работает до тех пор, пока я не захочу зациклить элементы. Исходя из того, что я вижу, я должен быть в состоянии передать myKey в качестве параметра для YamlScalarNode() для доступа к элементам под ним.
var items = (YamlSequenceNode)mapping.Children[new YamlScalarNode(myKey)];
Я получаю следующую ошибку, если я делаю:
An unhandled exception of type 'System.InvalidCastException' occurred in yamldotnet.exe
Additional information: Unable to cast object of type 'YamlDotNet.RepresentationModel.YamlMappingNode' to type 'YamlDotNet.RepresentationModel.YamlSequenceNode'.
При передаче "items" в качестве параметра в YamlScalarNode() он просто жалуется на то, что элемента там нет, что и следовало ожидать. Так как я не уверен, что мой учебник работает неправильно, я хотел бы немного помочь, как решить эту проблему дальше.
3 ответа
У вас слишком много всего происходит в одной строке кода. Создайте новый объект YamlScalarNode в одной строке, получите доступ к массиву в другой строке, приведите результирующий объект в другую строку. Таким образом, вы сузите проблемную область до одного шага.
Сообщение говорит вам, что вы извлекаете YamlMappingNode из массива, но вы приводите его к YamlSequenceNode. Что недопустимо, поскольку эти два типа явно не связаны между собой.
На ваш вопрос уже был дан правильный ответ, но я хотел бы отметить, что ваш подход, вероятно, не самый лучший для анализа файлов. Типы YamlDotNet.RepresentationModel.* Предлагают объектную модель, которая непосредственно представляет поток YAML и его различные части. Это полезно, если вы создаете приложение, которое обрабатывает или генерирует потоки YAML.
Если вы хотите прочитать документ YAML в граф объектов, лучше всего использовать класс Deserializer. С его помощью вы можете написать свой код следующим образом:
using(var reader = File.OpenText("blueprints.yaml")
{
var deserializer = new Deserializer();
var blueprintsById = deserializer.Deserialize<Dictionary<int, YamlBlueprint>>(reader);
// Use the blueprintsById variable
}
Разница лишь в том, что свойство Id YamlBlueprint
экземпляры не будут установлены, но это просто вопрос добавления этого:
foreach(var entry in blueprintsById)
{
entry.Value.Id = entry.Key;
}
Ну, это было довольно глупо... довольно сложно создать отображение чего-то, что содержит только один элемент. Я отредактировал репозиторий, связанный в OP, с рабочим примером на случай, если кто-то столкнется с той же проблемой.