How to get all 'Yamldotnet' values in 'File.yml'?

Asked

Viewed 199 times

2

I’m working on a.yml file and I want to get all the values it contains in that file. I’m using the reference Yamldotnet.Serialization.

What I want to do is take a certain value and display the properties of that certain value. But only by deserializing the "file.yml", I get a type of value with format Dictionary<object, object>.

Below I am "deserializing the file.yml" and "Serializing in the file.json"

YAML

groups:
  Default:
    default: true
    permissions:
    - essentials.kits.tools
    - essentials.kits.armor
    - essentials.balance
    - essentials.pay
    - essentials.sell
    - essentials.afk
    - essentials.help.*
    - essentials.clearinventory
    - essentials.enderchest
    - essentials.back
    - essentials.back.ondeath
    - essentials.delhome
    - essentials.home
    - essentials.home.bed
    - essentials.sethome
    - essentials.sethome.bed
    - essentials.tpa
    - essentials.tpaccept
    - essentials.tpahere
    - essentials.tpdeny
    - essentials.warp
    - essentials.signs.use.*
    - essentials.spawn
    inheritance:
    info:
      prefix: '&8[&7Peasent] '
      build: true
      suffix: ''
  Builder:
    default: false
    permissions:
    - essentials.gamemode
    - essentials.time
    - essentials.weather
    - essentials.time.set
    - essentials.bigtree
    - essentials.repair.*
    - essentials.workbench
    - essentials.break.bedrock
    - essentials.tp
    - worldedit.*
    inheritance:
    - default
    info:
      prefix: '&8[&6&lBuilder&8] '
      build: true
      suffix: ''
  VIP:
    default: false
    permissions:
    - essentials.gamemode
    - essentials.time
    - essentials.time.set
    - essentials.repair.*
    - essentials.tp
    - essentials.tphere
    inheritance:
    - default
    info:
      prefix: '&8[&6&lVIP&8] '
      build: true
      suffix: ''
  Donator:
    default: false
    permissions:
    inheritance:
    - vip
    info:
      prefix: '&8[&6&lDonator&8] '
      build: true
      suffix: ''
  Moderator:
    default: false
    permissions:
    - essentials.ban.*
    - essentials.tempban.*
    - essentials.kick.*
    - essentials.warp
    - essentials.warp.list
    - essentials.sethome.others
    - essentials.home.others
    inheritance:
    - donator
    info:
      prefix: '&8[&cModerator&8] '
      build: true
      suffix: ''
  ModeratorPlus:
    default: false
    permissions:
    - essentials.gamemode.others
    - essentials.spawn.others
    - heads.*
    inheritance:
    - moderator
    info:
      prefix: '&8[&cModerator&c&l+&8] '
      build: true
      suffix: ''
  Admin:
    default: false
    permissions:
    - essentials.banip
    - essentials.unbanip
    - essentials.unban
    - essentials.exp.*
    - essentials.fly.*
    inheritance:
    - moderatorplus
    info:
      prefix: '&8[&2Solider] '
      build: true
      suffix: ''
  AdminPlus:
    default: false
    permissions:
    - worldedit.*
    inheritance:
    - admin
    info:
      prefix: '&8[&2ADMIN&2&l+&8] '
      build: true
      suffix: ''
  Co-Owner:
    default: false
    permissions:
    - essentials.*
    inheritance:
    - adminplus
    info:
      prefix: '&8[&b&lCO&r-&bOWNER&8] '
      build: true
      suffix: ''
  Owner:
    default: false
    permissions:
    - '*'
    - -vanish.*
    inheritance:
    - co-owner
    info:
      prefix: '&8[&b&lOWNER&8] '
      build: true
      suffix: ''
  OP:
    default: false
    permissions:
    inheritance:
    - owner
    info:
      prefix: '&8[&e&lOP&8] '
      build: true
      suffix: ''

Code

using Newtonsoft.Json;
using System.IO;
using System.Windows.Forms;
using YamlDotNet.Serialization;
using System.Collections.Generic;

namespace GroupManager_JSon
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            getProperties();
        }

        public void getProperties()
        {
            // deserializando
            string path = "file.yml";
            var r = new StreamReader(path);
            var deserializer = new Deserializer();
            var yamlDynamic = deserializer.Deserialize<dynamic>(r);
            Dictionary<object, object> dic = new Dictionary<object, object>();

            var values = yamlDynamic.Values;
            dic = yamlDynamic;

            foreach (var item in dic.Values)
            {

            }

            // serializando
            JsonSerializer js = new JsonSerializer();
            var w = new StringWriter();
            js.Serialize(w, yamlDynamic);
            string jsonText = w.ToString();
            File.WriteAllText("file.json", jsonText);
        }
    }
}

In the deserialization of the variable "yamlDynamic", I realized that its type is:

Dictionary<object, object>

And within each "Values" of the "Keys" of this dictionary, it seems to contain more:

Dictionary<object, object>

Like in the picture:

inserir a descrição da imagem aqui

I can only pull those values with one variable dynamic, as in the variable values above. How can I deserializar the guy from Dictionary<object, object> for another type? Because I want to pull the types literally on not several types, for example, the object is a diverse guy, I don’t know if he’s a List<> or a Dictionary<>. Here I just want to spread all these kinds of values in one Classe, or form a single variable and within that variable, several types. Even if it is, a large type like:

Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> dicc = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>>();

It’s just an example.

What matters to me is to escape the "Object" without using the variable dynamic. And finally, pull the guy and work on this guy.

Anyone can help?

  • To make the Deserialize for a specific class need to have this class, otherwise you will have to work with dynamic because the code does not "know" the type. It has some class already created?

  • I don’t have the class yet, because as I change the properties of the.yml file, the class properties will be useless. And I don’t know how to spread the values like that :/

  • The process you are describing to define a type instead of Object is exactly to create a class that represents the structure to do the deserialization as @Joãomartins said

  • I get it, but how do I assemble the class according to the structure? I clean the JSON variable and see the types of values it has? To create the values?

1 answer

1


To deserialize with defined type needs a class

Below is a suggestion based on what you posted. If you change the format you need to adapt the class or alias of each property.

public partial class Security
{
    [YamlMember(Alias = "groups")]
    public Groups Groups { get; set; }
}

public partial class Groups
{
    [YamlMember(Alias = "Default")]
    public Admin Default { get; set; }

    [YamlMember(Alias = "Builder")]
    public Admin Builder { get; set; }

    [YamlMember(Alias = "VIP")]
    public Admin Vip { get; set; }

    [YamlMember(Alias = "Donator")]
    public Admin Donator { get; set; }

    [YamlMember(Alias = "Moderator")]
    public Admin Moderator { get; set; }

    [YamlMember(Alias = "ModeratorPlus")]
    public Admin ModeratorPlus { get; set; }

    [YamlMember(Alias = "Admin")]
    public Admin Admin { get; set; }

    [YamlMember(Alias = "AdminPlus")]
    public Admin AdminPlus { get; set; }

    [YamlMember(Alias = "Co-Owner")]
    public Admin CoOwner { get; set; }

    [YamlMember(Alias = "Owner")]
    public Admin Owner { get; set; }

    [YamlMember(Alias = "OP")]
    public Admin Op { get; set; }
}

public partial class Admin
{
    [YamlMember(Alias = "default")]
    public bool Default { get; set; }

    [YamlMember(Alias = "permissions")]
    public string[] Permissions { get; set; }

    [YamlMember(Alias = "inheritance")]
    public string[] Inheritance { get; set; }

    [YamlMember(Alias = "info")]
    public Info Info { get; set; }
}

public partial class Info
{
    [YamlMember(Alias = "prefix")]
    public string Prefix { get; set; }

    [YamlMember(Alias = "build")]
    public bool Build { get; set; }

    [YamlMember(Alias = "suffix")]
    public string Suffix { get; set; }
}

With the defined class you can do the deserialization by specifying the class:

string path = "file.yml";
Security security;
using (var r = new StreamReader(path)) {
   var deserializer = new Deserializer();
   security = deserializer.Deserialize<Security>(r);
}
  • I used the YAML that you posted here in my test. If it has changed it may have to adapt.

  • oops, my fault

Browser other questions tagged

You are not signed in. Login or sign up in order to post.