我有以下json结构:
{
"access:hasPermission": true,
"access:permission:assemble_document": true,
"access:permission:can:modify": true,
"access:permission:can:print": true,
"access:permission:can:print_degraded": true,
"access:permission:extract_content": true,
"access:permission:modify_annotations": true,
"doc:creator": "me",
"doc:description": "sample description",
"ping":"pong"
}
我只想递归地处理json,这样最终结果就会变成这样:
{
"access":{
"hasPermission":true,
"permission":{
"assemble_document": true,
"can":{
"modify": true,
"print": true,
"print_degraded": true,
},
"extract_content": true,
"modify_annotations": true,
}
},
"doc":{
"creator": "me",
"description": "sample description",
},
"ping":"pong"
}
我在Newtonsoft.Json 中使用C#
public static JObject Expand(this JObject jToken,char separator=':')
{
...
}
好的,我用下面的代码解决了我的问题:
这个方法在json数组中也很好
public static JToken Expand(this JToken jToken, string separators = ":.")
{
if (jToken is JValue jValue) return jValue;
JToken Empty() => JToken.Parse("{}");
jToken = JToken.Parse(jToken.ToString());
switch (jToken)
{
case JObject jObj:
{
var js = Empty();
foreach (var jProp in jObj.Descendants().OfType<JProperty>().ToArray())
{
if (jProp.Path.Contains("[")) continue;
var path = jProp.Path.Split(separators.ToCharArray());
var tmp = js;
foreach (var s in path)
{
if (tmp[s] == null)
{
tmp[s] = Empty();
}
tmp = tmp[s];
}
if (tmp.Parent is JProperty jParentProp)
{
if (jProp.Value is JValue)
{
jParentProp.Value = jProp.Value;
}
else
{
var x = JToken.Parse(jProp.Value.ToString()).Expand(separators);
jParentProp.Value = x;
}
}
else
{
//nothing to do here
;
}
}
foreach (var jArr in jObj.Descendants().OfType<JArray>().ToArray())
{
foreach (var jItem in jArr.ToArray())
{
jItem.Replace(jItem.Expand(separators));
}
}
return js;
}
case JArray jArray:
{
foreach (var jItem in jArray.ToArray())
{
jItem.Replace(jItem.Expand(separators));
}
return jArray;
}
default:
return jToken;
}
}