33 Stimmen

C# JSON-Struktur flachhalten

Ich habe ein JSON-Objekt in C# (dargestellt als ein Newtonsoft.Json.Linq.JObject-Objekt) und muss es in ein Dictionary umwandeln. Lass mich dir anhand eines Beispiels zeigen, was ich meine:

{
    "name": "test",
    "father": {
         "name": "test2"
         "age": 13,
         "dog": {
             "color": "brown"
         }
    }
}

Dies sollte ein Dictionary mit den folgenden Schlüssel-Wert-Paaren ergeben:

["name"] == "test",
["father.name"] == "test2",
["father.age"] == 13,
["father.dog.color"] == "brown"

Wie kann ich das machen?

1voto

Basierend auf dem Code, der von tymtam bereitgestellt wurde, aber auch Arrays unterstützt:

    public static IEnumerable> Flatten(this T data, string separator = ":") where T : class
    {
        var json = JsonSerializer.Serialize(data);

        string GetArrayPath(string path, string name, int idx) =>
            path == null ? $"{name}{separator}{idx}" : $"{path}{separator}{name}{separator}{idx}";
        IEnumerable<(string Path, JsonElement Element)> GetLeaves(string path, string name, JsonElement element) => element.ValueKind switch
        {
            JsonValueKind.Object => element.EnumerateObject()
                .SelectMany(child => GetLeaves(path == null ? name : $"{path}{separator}{name}", child.Name, child.Value)),
            JsonValueKind.Array => element.EnumerateArray()
                .SelectMany((child, idx) => child.ValueKind == JsonValueKind.Object
                        ? child.EnumerateObject().SelectMany(child => GetLeaves(GetArrayPath(path, name, idx), child.Name, child.Value))
                        : new[] { (Path: GetArrayPath(path, name, idx), child) }
                    ),
            _ => new[] { (Path: path == null ? name : $"{path}{separator}{name}", element) },
        };

        using JsonDocument document = JsonDocument.Parse(json); // Optionale JsonDocumentOptions options
        return document.RootElement.EnumerateObject()
            .SelectMany(p => GetLeaves(null, p.Name, p.Value))
            .ToDictionary(k => k.Path, v => v.Element.Clone().ToString()); //Klone, damit wir die Werte außerhalb von using verwenden können
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X