Augusto Henrique
Augusto Henrique

Reputation: 238

Represent string data to tree

I have the following data. This is a list of programs on my system.

[
  {
    "ID": 135,
    "CODIGO": 139,
    "NOME": "CADASTRO DE ANOS ATIVOS",
    "VISAO": "VANOSATIVOSCONTABIL",
    "CAMINHO": "Cadastros/Contabilidade/frm_AnosAtivosContabil.aspx, 139, ((VariaveisSistema)Session[VariaveisSistema]).UsuarioId.ToString().Trim(), frm_Visoes.aspx, , Nao"
  },
  {
    "ID": 59,
    "CODIGO": 35,
    "NOME": "CADASTRO DE CENTRO DE CUSTO",
    "VISAO": "VCENTROCUSTO",
    "CAMINHO": "Cadastros/Contabilidade/frm_CadastroCentroCusto.aspx, 035, ((VariaveisSistema)Session[VariaveisSistema]).UsuarioId.ToString().Trim(), frm_Visoes.aspx, , Nao"
  },
]

So, you can see that the program has a path like Cadastros/Contabilidade.

I need to conver the Cadastros/Contabilidade in a menu tree colapsable.

So the json data should look like this:

Cadastros 
    |
    | Contabilidade
         - frm_AnosAtivosContabil.aspx
         - frm_CadastroCentroCusto.aspx
         - frm_CadastroCFOP.aspx
         - ...

    | Globais
         - frm_AlteraFormacaoArvore.aspx
         - frm_AssociacaoCalendario.aspx
         - frm_AssociacaoItemTransferencia.aspx
         - ...

I am using C#. I managed to separate the programs along the way (group them). But I have not managed to separate them into menus.

The node structure is:

public class Node
{
    public IList<Programa> Programs { get; set; }
    public string Name { get; set; }
    public string FullName { get; set; }
    public Node Parent { get; set; }
    public IList<Node> Childrens { get; set; }
}

Program structure:

public class Programa
{
    public int Id { get; set; }
    public int Codigo { get; set; }
    public string Nome { get; set; }
    public string Visao { get; set; }        
    public IList<UsuarioPrograma> UsuariosPrograma { get; set; }
    public string Caminho { get; set; }
}

I can create the root node. But i dont kno how to proceed.

private void CreateNode(Programa programa)
{
    var paths = programa.Caminho.Split('/');

    // Verifica se já é o pai
    if (paths.Length == 1)
    {
        // Verifica se o nó já existe
        var node = Menu.FirstOrDefault(x => x.Name == paths[0]);

        if (node == null)
        {
            node = new Node();
            node.Name = paths[0];
            node.Programs = new List<Programa> { programa };

            Menu.Add(node);
        }

        else Menu.First(x => x.Name == paths[0]).Programs.Add(programa);
    }
}

Upvotes: 4

Views: 209

Answers (1)

coder_b
coder_b

Reputation: 1025

@augusto-henrique bit tricky but managed to bring the json object however you expecting to serialize, have a look this code and see whether this works for your requirements,

first I created a class to serialize the JSON you have

  public class Page
        {
            public int ID { get; set; }
            public int CODIGO { get; set; }
            public string NOME { get; set; }
            public string VISAO { get; set; }
            public string CAMINHO { get; set; }
        }

Then I am grouping the values and adding into dictionary objects as nested collection

var json1 = JsonConvert.DeserializeObject<List<Page>>
                        (File.ReadAllText(@"c:\temp\test1.json"));

            var root1 = json1.Select(x => x.CAMINHO)
                    .Select(x => x.Split(",")[0])
                    .Select(x => x.Split("/"))
                    .Select(x => new
                    {
                        level1 = x.First(),
                        level2 = x.Skip(1).First(),
                        level3 = x.Skip(2).First()
                    })
                    .GroupBy(x => new { x.level1, x.level2, x.level3 }, (key, grp) => new
                    {
                        Level1 = key.level1,
                        Level2 = key.level2,
                        Level3 = key.level3,
                        groups = grp
                    });
            var jsonObject = new Dictionary<string, object>();
            foreach (var level1 in root1)
            {
                if (!jsonObject.ContainsKey(level1.Level1))
                {
                    jsonObject.Add(level1.Level1, new Dictionary<string, object[]>());
                }
                if (!((Dictionary<string, object[]>)jsonObject[level1.Level1]).ContainsKey(level1.Level2))
                    ((Dictionary<string, object[]>)jsonObject[level1.Level1]).Add(level1.Level2, new[] { level1.Level3 });
                else
                {
                    var list = (((Dictionary<string, object[]>)jsonObject[level1.Level1])[level1.Level2]).ToList();
                    list.Add(level1.Level3);
                    ((Dictionary<string, object[]>)jsonObject[level1.Level1])[level1.Level2] = list.ToArray();
                }  

            }
            var jsonText = JsonConvert.SerializeObject(jsonObject);

the result of jsonText would look like, hope from this you can develop further., may require some refactoring,

JSON Document

Upvotes: 2

Related Questions