sPENKMAN
sPENKMAN

Reputation: 91

Seeking guidance reading .yaml files with C#

Two months later: The YAML (Eve Online blueprint.yaml) file I tried to parse changed a huge deal which also made it much easier to parse using de deserializer. If someone (for whatever reason) would like to see the code, it's updated on https://github.com/hkraal/ParseYaml


Based on the comment of Steve Wellens I've adjusted the code to do less things at once. It didn't matter in the error itself. I've created another project (Example1) in my solution to test the actual example found on aaubry.net I referenced to earlier.

It gave me the same error when using an "dynamic" key which lead to my current conclusion: There is a difference between:

items:
    - part_no:   A4786

and

items:
    part_no:   A4786

The first is being used in the example which I (wrongly) assumed I could apply to my .yaml file which is using the second syntax.

Now it remains to find out how I can get the 'child' elements of my key with the syntax used in my yaml file...


As C# is used at work I started thinking about a nice project to learn about various aspects of the language while having a direct goal to work towards. However I'm hitting my first wall quite early in my project parsing a Yaml file. My goal is to create an List of YamlBlueprint objects as defined in YamlBlueprint.cs but I don't even get to the end of the Yaml file.

I've setup a testcase on github which demonstrates the problem: https://github.com/hkraal/ParseYaml

The example on http://www.aaubry.net/page/YamlDotNet-Documentation-Loading-a-YAML-stream works up untill I want to loop trough the items. Based on what I see I should be able to give myKey as parameter to the YamlScalarNode() to access the items below it.

var items = (YamlSequenceNode)mapping.Children[new YamlScalarNode(myKey)];

I'm gettting the following error if I do:

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'.

When passing "items" as parameter to YamlScalarNode() it just complains about the item not being there which is to be expected. As I'm not sure where my toughttrain is going wrong I would love a bit assistance on how to troubleshoot this further.

Upvotes: 8

Views: 14933

Answers (3)

Antoine Aubry
Antoine Aubry

Reputation: 12469

Your question has already been correctly answered, but I would like to point out that your approach is probably not the best one for parsing files. The YamlDotNet.RepresentationModel.* types offer an object model that directly represents the YAML stream and its various parts. This is useful if you are creating an application that processes or generates YAML streams.

When you want to read a YAML document into an object graph, the best approach is to use the Deserializer class. With it you can write your code as follows:

using(var reader = File.OpenText("blueprints.yaml")
{
    var deserializer = new Deserializer();
    var blueprintsById = deserializer.Deserialize<Dictionary<int, YamlBlueprint>>(reader);

    // Use the blueprintsById variable
}

The only difference is that the Id property of the YamlBlueprint instances won't be set, but that's just a matter of adding this:

foreach(var entry in blueprintsById)
{
    entry.Value.Id = entry.Key;
}

Upvotes: 4

sPENKMAN
sPENKMAN

Reputation: 91

Well that was kinda stupid... it's kind of hard to create an mapping of something which only contains one element. I've edited the repo linked in the OP with an working example in case somebody runs into the same problem.

Upvotes: 0

Steve Wellens
Steve Wellens

Reputation: 20620

You have too much stuff going on in one line of code. Create a new YamlScalarNode object in one line, access the array in another line, cast the resultant object in another line. That way, you'll narrow down the problem area to a single step.

The message is telling you that you are retrieving a YamlMappingNode from the array but you are casting it to a YamlSequenceNode. Which is not allowed since the two types are obviously not related.

Upvotes: 3

Related Questions