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