【问题标题】:Json.Net expand JToken fields base on conventionJson.Net 根据约定扩展 JToken 字段
【发布时间】:2021-04-03 22:56:19
【问题描述】:

我有以下 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"
}

我正在使用 C# 和 Newtonsoft.Json

public static JObject Expand(this JObject jToken,char separator=':')
{
  ...
}

【问题讨论】:

  • 很好,您在哪里尝试解决问题?大多数用户无法使用已删除的答案,但您和 10k 代表除外
  • @PavelAnikhouski 我的第一个方法在数组上表现不佳,所以我不得不永久删除它直到修复,现在发布更新版本

标签: c# json recursion json.net


【解决方案1】:

好的,我用下面的代码解决了我的问题:
而且这个方法在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;
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    相关资源
    最近更新 更多