c#解析轻松的json来制作一棵树

时间:2017-08-23 10:32:12

标签: c# json regex validation tree

所以我需要解析看起来相似的文件:

{
pl: {
    GENERIC: {
        BACK: "COFNIJ",
        WAIT: "CZEKAJ",

        PAGES: {
            ABOUTME: {
                ID: "ID",
            },
            INFO: {
                STATUS: "STATUS",
            }
        }
    },

    TOP_MENU: {
        LOGGED: "Zalogowany",
        OPTIONS: "Opcje",
    }
},

en: {
    GENERIC: {
        BACK: "BACK",
        WAIT: "WAIT",

        PAGES: {
            ABOUTME: {
                ID: "ID",
            },
            INFO: {
                STATUS: "STATUS",
            }
        }
    },

    TOP_MENU: {
        LOGGED: "Logged",
        OPTIONS: "Options",
    }
}

}

但我不知道该文件将包含多少元素,因此我无法创建解析此文件的类

  1. 我的第一个问题是如何在文件中用双引号包含c#“no quotes”元素,以使这个文件json可解析?
  2. 如何将上面的json文件解析为树数据结构,所以它看起来像这样: Sample tree ,所以我可以在控制台的每个叶子节点上输出路径,“en”和“pl”子树中的值?
    例如: path:generic / back en:“back”pl:“cofnij”。
  3. 我已经尝试过使用Dictionary<string, dynamic> dictionary = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(file); 获取主键,将上面的轻松json转换为有效的json,但我认为树结构将是更有效的方法。 谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

您的第一个问题已在此处提出:Parsing non-standard JSON

第二个问题听起来有点像这样:你的第一个问题已在这里提出:Deserialize JSON into C# dynamic object?

您可以创建动态对象

   dynamic myObj =   JsonConvert.DeserializeObject(json);
   foreach (Newtonsoft.Json.Linq.JProperty jproperty in myObj)
   {
         //..
   }

然后预处理它以创建树结构。这有助于:How do I reflect over the members of dynamic object?

修改

这是通过迭代属性将您的反序列化动态转换为树结构的方法:

    public void Convert()
    {
        dynamic myObj = JsonConvert.DeserializeObject(json);
        PrintObject(myObj, 0);
    }

    private void PrintObject(JToken token, int depth)
    {
        if (token is JProperty)
        {
            var jProp = (JProperty)token;
            var spacer = string.Join("", Enumerable.Range(0, depth).Select(_ => "\t"));
            var val = jProp.Value is JValue ? ((JValue)jProp.Value).Value : "-";

            Console.WriteLine($"{spacer}{jProp.Name}  -> {val}");

            foreach (var child in jProp.Children())
            {
                PrintObject(child, depth + 1);
            }
        }
        else if (token is JObject)
        {
            foreach (var child in ((JObject)token).Children())
            {
                PrintObject(child, depth + 1);
            }
        }
    }