Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can we get all the values of available keys within Yaml file which has deep hierarchy. Also, If I just need to get all the keys available. #686

Closed
Coding-With-Ashish opened this issue Apr 27, 2022 · 6 comments

Comments

@Coding-With-Ashish
Copy link

Coding-With-Ashish commented Apr 27, 2022

If I do not have idea about how many keys or with what hierarchy keys could be present in YAML , is it possible to write a generic method which fetches all the keys and values available with in yaml file given of any structure.

@EdwardCooke
Copy link
Collaborator

When you deserialize the yaml without specifying the object type it looks like it comes back as a Dictionary<object, object>. Where the key object is actually a string. The value part of that dictionary is either the value or another Dictionary<object, object>.

Here's some code that will dump out all of the keys in a yaml file of an arbitrary format:

using YamlDotNet.Benchmark;
using YamlDotNet.Serialization;

var deserializer = new DeserializerBuilder().Build();
var o = deserializer.Deserialize(new StringReader(@"
a:
  b:
    hello: world
  c:
    i: am
    a: martian
"))!;

var allKeys = GetKeys((Dictionary<object, object>)o, string.Empty);

foreach (var key in allKeys)
{
    Console.WriteLine(key);
}

string[] GetKeys(Dictionary<object, object> values, string path)
{
    var keys = new List<string>();
    foreach (var kvp in values)
    {
        if (kvp.Value is Dictionary<object, object> x)
        {
            keys.AddRange(GetKeys((Dictionary<object, object>)kvp.Value, $"{path}:{kvp.Key}"));
        }
        else
        {
            keys.Add($"{path}:{kvp.Key}={kvp.Value}");
        }
    }
    return keys.ToArray();
}

Result:

:a:b:hello=world
:a:c:i=am
:a:c:a=martian

Hopefully that helps.

@EdwardCooke
Copy link
Collaborator

Closing. Reopen this if you still need help.

@gius
Copy link

gius commented Nov 10, 2022

When you deserialize the yaml without specifying the object type it looks like it comes back as a Dictionary<object, object>. Where the key object is actually a string.

Is it possible to make it Dictionary<string, object> by default?

@EdwardCooke
Copy link
Collaborator

The key doesn’t have to be a string. It can be an actual object as well. The yaml spec doesn’t require it to be a scalar.

@gius
Copy link

gius commented Nov 10, 2022

Oh, I understand. And is there a way to manually configure a particular deserializer to convert the Dictionary<object, object> to a string-keyed one? I've tried a custom IYamlTypeConverter, but it is too low-level.

Edit: it seems that a custom INodeDeserializer registered instead of DictionaryNodeDeserializer is the solution.

Thank you guys for this great library!

@ohads-MSFT
Copy link

When you deserialize the yaml without specifying the object type it looks like it comes back as a Dictionary<object, object>. Where the key object is actually a string. The value part of that dictionary is either the value or another Dictionary<object, object>.

Reference (and slight correction) for this: #332 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants