@mcalsyn Thank you for your quick response. With your guidance I was able to do exactly what I was looking to do.
I do have a couple of follow-up questions.
- Looking at the Json Deserialize code it looks like the ‘JsonConverter.Deserialize()’ can return ‘JObject’ or an ‘JArray’ object. I could not figure out what in the Json string would make it return a ‘JArray’ as the top level object. Right now I’m assuming it will only return a ‘JObject’ in the root of the object. Is this a safe assumption?
- I notice that string values have quotes ("") around them. Can I remove these with JsonConvert somehow? If not, I can build a function to detect and parse them out.
- Any other feedback is welcome.
Output
object1:property2:1 = 3
object1:property2:5 = 7
object1:property1 = "value1"
object1:property2:0 = 2
object1:property2:4 = 6
object1:property2:3 = 5
object1:property2:2 = 4
key2 = "value2"
key1 = 1
Code
internal sealed class JsonConfigurationParser
{
private readonly Hashtable _data = new Hashtable();
public static Hashtable Parse(Stream input)
=> new JsonConfigurationParser().ParseStream(input);
private Hashtable ParseStream(Stream input)
{
try
{
JToken token = JsonConverter.Deserialize(input);
if (token is JObject jobj)
{
foreach (JProperty member in jobj.Members)
{
foreach (DictionaryEntry pair in GetNode(member))
{
_data.Add(
pair.Key.ToString().ToLower(),
pair.Value.ToString().Trim('"').TrimEnd('"')
);
}
}
}
if (token is JArray jarray)
{
for (int i = 0; i < jarray.Length; i++)
{
var property = new JProperty($"root{i}", jarray[i]);
foreach (DictionaryEntry pair in GetNode(property))
{
_data.Add(
pair.Key.ToString().ToLower(),
pair.Value.ToString().Trim('"').TrimEnd('"')
);
}
}
}
}
catch
{
throw new FormatException();
}
return _data;
}
private static Hashtable GetNode(JProperty node)
{
var items = new Hashtable();
if (node.Value is JObject jobj)
{
foreach (JProperty member in jobj.Members)
{
var key = string.Concat(node.Name, ":", member.Name);
var values = GetNode(new JProperty(key, member.Value));
foreach (DictionaryEntry pair in values)
{
items.Add(pair.Key, pair.Value);
}
}
return items;
}
if (node.Value is JArray jarray)
{
for (int i = 0; i < jarray.Length; i++)
{
var key = string.Concat(node.Name, ":", i);
var values = GetNode(new JProperty(key, jarray[i]));
foreach (DictionaryEntry pair in values)
{
items.Add(pair.Key, pair.Value);
}
}
return items;
}
items.Add(node.Name, node.Value);
return items;
}
}