首页 > 其他分享 >JsonConfigurationFileParser

JsonConfigurationFileParser

时间:2024-09-11 22:05:12浏览次数:11  
标签:JsonConfigurationFileParser Name private Demo1 var new public

internal class Program
{
    static async Task Main(string[] args)
    {
        var root = new Root
        {
            Demo1 = new Demo1
            {
                Name = "Demo1",
                Data = new Demo2 { Name = "Demo2" }
            },
            List1 = new List<Demo2> {
              new Demo2{ Name ="a1" },
              new Demo2{ Name ="a2" },
             }
        };
        var json = JsonConvert.SerializeObject(root);

        var dic = JsonConfigurationFileParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(json)));

        foreach (var kv in dic)
        {
            Console.WriteLine($"{kv.Key} = {kv.Value}");
        }
    }
}

public class JsonConfigurationFileParser
{
    private readonly Dictionary<string, string?> _data = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
    private readonly Stack<string> _paths = new Stack<string>();
    private const string KeyDelimiter = ":";

    public static IDictionary<string, string?> Parse(Stream input)
        => new JsonConfigurationFileParser().ParseStream(input);

    private Dictionary<string, string?> ParseStream(Stream input)
    {
        var jsonDocumentOptions = new JsonDocumentOptions
        {
            CommentHandling = JsonCommentHandling.Skip,
            AllowTrailingCommas = true,
        };

        using var doc = JsonDocument.Parse(input, jsonDocumentOptions);

        if (doc.RootElement.ValueKind != JsonValueKind.Object)
        {
            throw new FormatException("JSON root must be an object.");
        }

        VisitObjectElement(doc.RootElement);

        return _data;
    }

    private void VisitObjectElement(JsonElement element)
    {
        var isEmpty = true;

        foreach (var property in element.EnumerateObject())
        {
            isEmpty = false;
            EnterContext(property.Name);
            VisitValue(property.Value);
            ExitContext();
        }

        SetNullIfElementIsEmpty(isEmpty);
    }

    private void VisitArrayElement(JsonElement element)
    {
        var index = 0;

        foreach (var arrayElement in element.EnumerateArray())
        {
            EnterContext(index.ToString());
            VisitValue(arrayElement);
            ExitContext();
            index++;
        }

        SetNullIfElementIsEmpty(isEmpty: index == 0);
    }

    private void VisitValue(JsonElement value)
    {
        switch (value.ValueKind)
        {
            case JsonValueKind.Object:
                VisitObjectElement(value);
                break;
            case JsonValueKind.Array:
                VisitArrayElement(value);
                break;
            case JsonValueKind.Number:
            case JsonValueKind.String:
            case JsonValueKind.True:
            case JsonValueKind.False:
            case JsonValueKind.Null:
                string key = _paths.Peek();
                if (_data.ContainsKey(key))
                {
                    throw new FormatException("Key Is Duplicated");
                }
                _data[key] = value.ToString();
                break;
            default:
                throw new FormatException("Unsupported JSONToken");
        }
    }

    private void SetNullIfElementIsEmpty(bool isEmpty)
    {
        if (isEmpty && _paths.Count > 0)
        {
            _data[_paths.Peek()] = null;
        }
    }


    private void EnterContext(string context)
    {
        _paths.Push(_paths.Count > 0 ? _paths.Peek() + KeyDelimiter + context : context);
    }

    private void ExitContext()
    {
        _paths.Pop();
    }
}

public class Root
{
    public Demo1 Demo1 { get; set; }
    public List<Demo2> List1 { get; set; }
    public List<Demo2> List2 { get; set; }
}

public class Demo1
{
    public string Name { get; set; }
    public Demo2 Data { get; set; }
}

public class Demo2
{
    public string Name { get; set; }
}

输出

Demo1:Name = Demo1
Demo1:Data:Name = Demo2
List1:0:Name = a1
List1:1:Name = a2
List2 =

标签:JsonConfigurationFileParser,Name,private,Demo1,var,new,public
From: https://www.cnblogs.com/readafterme/p/18409068

相关文章