es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Obtén todas las rutas y tipos de un JSON con System.Text.Json (.NET 6)

Escribí el siguiente método para obtener todas las combinaciones de Ruta + Tipo para todas las claves en un JSON mediante JSON.NET:

public static IEnumerable<string> GetKeys(this JToken jToken)
{
    var keys = new List<string>();

    var jTokenKey = $"{(string.IsNullOrEmpty(jToken.Path) ? "{/ROOT/}" : jToken.Path)}-{jToken.Type}";
    keys.Add(jTokenKey);
    foreach (var child in jToken.Children())
    {
        var key = child.GetKeys();
        keys.AddRange(key);
    }
    return keys;
}

Necesito una combinación de Ruta + Tipo para todos los elementos de un JSON. ¿Alguien puede ayudarme a obtener el mismo resultado (o similar) con System.Text.Json?

Ejemplo:

{
    "a": [{
            "b": "bbb",
            "c": "ccc",
            "d": "ddd"
        }
    ],
    "e": "2021-12-29T14:20:21.948Z",
    "f": {
        "g": [{
                "h": "hhh",
                "i": "iii",
                "j": null,
                "k": true,
                "l": false,
                "m": "2021-12-29T14:20:21.948Z",
                "n": 10
            }
        ]
    }
}

Resultado de JSON.NET:

$-Object
a-Property
a-Array
a[0]-Object
a[0].b-Property
a[0].b-String
a[0].c-Property
a[0].c-String
a[0].d-Property
a[0].d-String
e-Property
e-Date
f-Property
f-Object
f.g-Property
f.g-Array
f.g[0]-Object
f.g[0].h-Property
f.g[0].h-String
f.g[0].i-Property
f.g[0].i-String
f.g[0].j-Property
f.g[0].j-Null
f.g[0].k-Property
f.g[0].k-Boolean
f.g[0].l-Property
f.g[0].l-Boolean
f.g[0].m-Property
f.g[0].m-Date
f.g[0].n-Property
f.g[0].n-Integer

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Desafortunadamente, System.Text.Json no proporciona un equivalente a la propiedad Path de JSON.NET, lo que dificulta lograr el mismo resultado que el método GetKeys mostrado anteriormente. Sin embargo, aún es posible obtener un resultado similar al recorrer de manera recursiva el objeto JSON y construir las claves deseadas manualmente basándose en los nombres de las propiedades y los tipos de valores.

    Aquí tienes un ejemplo de implementación utilizando System.Text.Json para lograr el mismo resultado que el método GetKeys de JSON.NET:

    public static IEnumerable<string> GetKeys(JsonElement element, string path = "")
    {
        var keys = new List<string>();
    
        // Agregar clave para el elemento actual
        keys.Add($"{path}-{element.ValueKind}");
    
        // Recorrer de manera recursiva los elementos hijos
        switch (element.ValueKind)
        {
            case JsonValueKind.Object:
                foreach (var property in element.EnumerateObject())
                {
                    keys.AddRange(GetKeys(property.Value, $"{path}.{property.Name}"));
                }
                break;
            case JsonValueKind.Array:
                for (int i = 0; i < element.GetArrayLength(); i++)
                {
                    keys.AddRange(GetKeys(element[i], $"{path}[{i}]"));
                }
                break;
        }
    
        return keys;
    }
    

    Ten en cuenta que esta implementación utiliza el enumerador JsonValueKind para determinar el tipo de cada elemento JSON, lo cual corresponde a la propiedad Type utilizada por el método GetKeys de JSON.NET. El parámetro path se utiliza para llevar un registro de la ruta actual dentro del objeto JSON.

    Aplicar este método al JSON de muestra proporcionado en la pregunta produciría el siguiente resultado:

    -Object
    .a-Array
    .a[0]-Object
    .a[0].b-String
    .a[0].c-String
    .a[0].d-String
    .e-String
    .f-Object
    .f.g-Array
    .f.g[0]-Object
    .f.g[0].h-String
    .f.g[0].i-String
    .f.g[0].j-Null
    .f.g[0].k-True
    .f.g[0].l-False
    .f.g[0].m-String
    .f.g[0].n-Number
    

    Como se puede ver, el formato de las claves utilizado por System.Text.Json es ligeramente diferente al utilizado por JSON.NET, pero la información proporcionada es la misma. Puedes modificar el formato de las claves según tus necesidades.

Comments are closed.