两个月后: 我试图解析的YAML(Eve Online blueprint.yaml)文件改变了很多,这也使得使用de deserializer更容易解析。如果某人(无论出于何种原因)想要查看代码,则会在https://github.com/hkraal/ParseYaml
上更新根据Steve Wellens的评论我已经调整了代码,以便一次做更少的事情。错误本身并不重要。我在我的解决方案中创建了另一个项目(Example1)来测试我之前引用的aaubry.net上的实际示例。
当使用“动态”键导致我目前的结论时,它给了我同样的错误: 以下是有区别的:
items:
- part_no: A4786
和
items:
part_no: A4786
第一个是在我(错误地)假设我可以应用于使用第二种语法的.yaml文件的示例中使用。
现在我仍然需要了解如何使用yaml文件中使用的语法来获取密钥的'child'元素...
当C#在工作中使用时,我开始考虑一个很好的项目来学习语言的各个方面,同时有一个直接的目标来努力。但是我在解析Yaml文件的项目中很早就打到了我的第一个墙。我的目标是创建YamlBlueprint.cs中定义的YamlBlueprint对象列表,但我甚至没有到达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()时,它只是抱怨项目不在那里是预期的。由于我不确定我的Toughttrain哪里出错了,我会对如何进一步排除故障提供一些帮助。
答案 0 :(得分:4)
您的问题已经得到正确回答,但我想指出您的方法可能不是解析文件的最佳方法。 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
}
唯一的区别是YamlBlueprint
实例的Id属性不会被设置,但这只是添加此内容的问题:
foreach(var entry in blueprintsById)
{
entry.Value.Id = entry.Key;
}
答案 1 :(得分:3)
你在一行代码中有太多的东西。在一行中创建一个新的YamlScalarNode对象,在另一行中访问该数组,将结果对象转换为另一行。这样,您就可以将问题区域缩小到一个步骤。
该消息告诉您正在从阵列中检索YamlMappingNode,但是您将其转换为YamlSequenceNode。这是不允许的,因为这两种类型显然没有关系。
答案 2 :(得分:-1)
那有点愚蠢......创建一个只包含一个元素的东西的映射很难。我已经编辑了OP中链接的repo,并提供了一个工作示例,以防有人遇到同样的问题。