【问题标题】:JSON.net parent keyJSON.net 父键
【发布时间】:2016-05-10 06:22:49
【问题描述】:

我很难使用 JSON.net 获取我的 JSON 对象的父键/属性/属性。也就是说,我想要 outermost 属性名称,作为一个字符串,而不事先/直观地知道它是什么。我目前正在迭代一组 KeyValuePair 项目,并尝试为每个项目从看起来像的东西中注销父项

{"parentKey": 
 {
  "Name": "Name",
  "Id": "123",
  "Other": null,
  "nestedArr": 
   [
    "idx0", 
    "idx1",
    "idx2"
   ]
 }
}

keyValue.Value.Ancestors()keyValue.Value.Parent 我都试过了。对于前者,我得到了看起来是函数定义的东西......我实际上不确定它是什么:Newtonsoft.Json.Linq.JToken+<GetAncestors>d_ _ 42。完全被这弄糊涂了,因为根据我在这里搜到的使用示例,我将它作为标准使用。

对于后者,我注销了整个对象,或者似乎是整个前面的 KeyValuePair,而不仅仅是我想要的字符串“parentKey”。 JSON.net 文档就显式使用示例和预期内容而言并不是最好的(或者可能只是 C# 的新手,我无法理解它们),但无论如何,我很友善不清楚为什么会发生这种情况以及如何完成我想要的。这就是我正在尝试的:

foreach (var keyValue in jObjList[0])  //jObjList is a List<JObject> defined above
{
    Console.WriteLine(keyValue.Value.Ancestors());
    Console.WriteLine(keyValue.Value.Parent);
    if (keyValue.Value.GetType() == typeof(JObject))//same block goes for if it's typeof(JArray)
    {
      Console.WriteLine(keyValue.Key);
    }
}

编辑:在给定的 JSON 中,以及在上面定义的循环中,例如,为了获取我的父键(这就是我所说的),我的代码只是说, if (keyValue.Value.GetType() == typeof(JObject),将 keyValue.Key 写入控制台,如果 getType() 是 JArray 也是如此。在任何一种情况下,keyValue.Key 都是父键,如果这有意义的话。我的意思是说它是一个指向另一个数组或对象的属性。我的问题是,当我递归地执行这个循环时,当我进入嵌套数组或对象时,我的代码无法意识到这一点,尽管目前有一个新的“父键”,就像nestedArr ,例如,nestedArr 的父键仍然是“parentKey”。

代码被删减了,但就是这样。

欢迎和感谢所有澄清和更正。谢谢。

【问题讨论】:

    标签: c# json json.net key-value


    【解决方案1】:

    您看到Newtonsoft.Json.Linq.JToken+&lt;GetAncestors&gt;d_ _ 42Console.WriteLine(keyValue.Value.Ancestors()),因为Ancestors 是一个IEnumerable&lt;T&gt;,其评估是lazy,而不是一个显式集合。您看到的是尚未评估的枚举的 ToString() 输出。

    如果您要做的是爬上给定JToken 的父列表并找到具有"parentKey" 属性的最低父列表,然后获取该parentKey 的值,那么这就是您的方法会这样做:

        JToken token = keyValue.Value; // Here I'm declaring JToken explicitly for clarity.  Normally I would use var token = ...
    
        var parentKey = token.AncestorsAndSelf()     // Climb up the json container parent/child hierachy
            .Select(p => p.SelectToken("parentKey")) // Get the "parentKey" property in the current parent (if present)
            .FirstOrDefault(k => k != null);         // Return the first one found.
    
        Console.WriteLine(parentKey);
    

    更新

    要在 JSON 容器层次结构中获取 JSON 属性 highest 的名称,您可以:

        var name = token.AncestorsAndSelf() // Walk up the list of ancestors
            .OfType<JProperty>()            // For each that is a property
            .Select(p => p.Name)            // Select the name
            .LastOrDefault();               // And return the last (topmost).
    

    更新 2

    如果您要查找 JSON 文件中出现的 first 属性名称,您可以使用 JContainer.DescendantsAndSelf() 执行以下操作:

        var json = @"[{""parentKey"": 
         {
          ""Name"": ""Name"",
          ""Id"": ""123"",
          ""Other"": null,
          ""nestedArr"": 
           [
            ""idx0"", 
            ""idx1"",
            ""idx2""
           ]
         }
        }]";
    
        var root = (JContainer)JToken.Parse(json);
        var name = root.DescendantsAndSelf() // Loop through tokens in or under the root container, in document order. 
            .OfType<JProperty>()             // For those which are properties
            .Select(p => p.Name)             // Select the name
            .FirstOrDefault();               // And take the first.
    
        Debug.WriteLine(name); // Prints "parentKey"
    

    JContainer表示可以包含子节点的JSON节点,例如对象或数组。)

    【讨论】:

    • 我不太明白 lambda 在您的示例中是如何工作的。你能评论一下那里发生了什么吗?另外,我需要一种匿名访问“parentKey”的方法,如果你愿意的话。我不知道“parentKey”会是什么,所以我不能将它作为参数传递。我只需要以动态方式知道 keyValuePair 的最外层属性是什么。为了清楚起见,我将编辑我的 Q。
    • @spb - 如果您可以编辑您的问题以包含 JSON 的完整示例以及您要打印到控制台的内容,我可能会更清楚地解释。
    • 感谢您注释掉代码。 :) 真的很有帮助。希望我的编辑能够阐明我正在努力完成的工作/正在使用的内容
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多