首页 > 解决方案 > 使用嵌套结构迭代 JSON

问题描述

我有一个具有以下结构的 JSON:

    data": {
        "password": {
          "en": "Password",
          "ar": "Password",
          "zh": "Password",
          ... 
           },
          "confirmPassword": {
              "en": "Confirm password",
              "ar": "Confirm password",
           ...
          },
         "addressInputStrings": {
              "en": {
                  "search": "Address",
                  "placeholder": "Start typing your address",
                  "addressNotListed": "My address is not listed",
                  "country": "Country of residence",
                   "street": "Street",
                   ...
                  }
       "fileUploadStrings"
            {
           "en": 
               {
        "required": "Please upload a document.",
        "fileUploadSuccessful": "File uploaded successfully: ",
        "uploadError": {
         "multipartContentTypeError": "The request couldn't be processed (Error 1)",
         ...

基本上“数据”是根,它有许多属性,每个属性都有一个语言代码列表。该值通常是一个字符串。有时会有第二层嵌套,有时甚至是第三层。

我需要遍历 JSON 并获得以下输出

[key] (tab) [value of "en"]

如果 "en" 的值不是字符串而是另一个对象,那么

[key].[nested key (in "en")] (tab) [value]

如果还有另一层嵌套,那么

[key].[nested key (in "en")].[nested nested key] (tab) [value]

因此,对于示例,输出将如下所示:

password (tab) Passsword
confirmPassword (tab) Confirm password
addressInputStrings.search (tab) Address
addressInputStrings.addressInputStrings.placeholder (tab) Start typing your address
addressInputStrings.addressNotListed (tab) My address is not listed
addressInputStrings.country (tab) Country of residence
addressInputStrings.street (tab) Street
fileUploadStrings.required (tab) Please upload a document
fileUploadStrings.fileUploadSuccessful (tab) File uploaded successfully: 
fileUploadStrings.uploadError.multipartContentTypeErrorThe (tab) request couldn't be processed (Error 1) 

我认为使用 Newtonsoft.Json 会很容易,但这就像图书馆正在积极地与我作斗争。当我尝试在 JObject 上迭代子代时,我得到的是 Jproperties 而不是 JObjects,我希望在其中得到第一个子代,我再次得到整个集合,我不断地左右出现异常,我们不要忘记几乎没有任何东西想要评估当我在调试器中暂停时的 Watch 窗口,因此无法进行实验。唯一的选择是修改、构建、调试、出错、重复。

我能得到一个快速而肮脏的解决方案吗?谢谢你。

标签: jsonjson.net

解决方案


听起来问题的根源在于您误解了 Json.Net 的LINQ-to-JSON API的设计。AJObject永远不能直接包含另一个JObject。AJObject只包含JProperty对象。每个JProperty都有一个名称和一个值。a 的值JProperty又可以是另一个JObject(或者它可以是 aJArrayJValue)。有关层次结构中关系的更多信息,请参阅JContainer 、JObject、JToken 和 Linq 混淆的答案JToken

了解了层次结构后,得到想要的输出的关键是Descendants()扩展方法。这将允许您使用简单的循环进行递归遍历。为了得到你的输出,你基本上是在寻找整个 JSON中每个叶子的Path和。您可以通过检查 是否为来识别叶子。ValueJPropertyValueJValue

所以,把它们放在一起,这就是你的做法(我在这里假设 C#,因为你没有在你的问题中指定一种语言):

var root = JObject.Parse(json);
var leafProperties = root.Descendants()
                         .OfType<JProperty>()
                         .Where(p => p.Value is JValue);

foreach (var prop in leafProperties)
{
    Console.WriteLine($"{prop.Path}\t{prop.Value}");
}

小提琴:https ://dotnetfiddle.net/l5Oqfb


推荐阅读