0

我在这里有一个小提琴: https ://dotnetfiddle.net/x6u5wH

我有两个问题,但公平地说,我会将它们分成两个帖子。发布后,我将在本文顶部添加指向第二个问题的链接。

总结 如果您运行上述小提琴,您将看到结果显示正在处理的 JProperty。美好的。

问题是“Immediate Ancestor Property Name”的值,目前显示的是预期值。但是,如果我希望祖先的值显示作为最近父的祖先的 JProperty 名称怎么办?我将解释我所说的“最近的父母”是什么意思,因为它可能有一个我不知道的实际 JSON 术语。

为了说明,让我们关注 JSON 中的 Data7 属性。请注意,它是 JArray Data5 中的第二个元素(Data6 是第一个元素)。

问题 我想做的是创建一个 Linq 查询,它查看当前属性,然后沿着祖先树向上查找最近的父属性。从 Data8 开始,最近的父节点是 Data7。但是,与 Data7 最接近的父级将是 Data4,而不是 Data5。我不认为 Data5 是最近的父级,因为 Data5 是一个包含 Data6 和 Data7 的 JArray。当涉及 JArrays 时,我想要 JArray 的父级,无论是 JArray 还是 JObject。Data6 的父级也是 Data4。

Data4 的父级是 Data3;对于 Data3,父级是 Data2;对于 Data2,父级将是 Data1(Data 将有一个空/空父级)。

谢谢。

PS如果小提琴消失了,这里是有问题的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;

    public class Program
    {
        public static void Main()
        {
            string json = @"{
  ""Data1"": {
    ""SPECIAL"": ""QQ01"",
    ""AA"": ""QQ"",
    ""BB"": ""QQ"",
    ""Data2"": [
      {
        ""SPECIAL"": ""QQ02"",
        ""AA"": ""QQ"",
        ""BB"": ""QQ"",
        ""CC"": ""QQ"",
        ""Data3"": [
          {
            ""SPECIAL"": ""QQ03"",
            ""AA"": ""QQ"",
            ""CC"": ""QQ"",
            ""Data4"": [
              {
                ""SPECIAL"": ""QQ04"",
                ""AA"": ""QQ"",
                ""CC"": ""QQ"",
                ""Data5"": [
                  {
                    ""SPECIAL"": ""QQ05"",
                    ""AA"": ""QQ"",
                    ""CC"": ""QQ"",
                    ""Data6"": [
                      {
                        ""SPECIAL"": ""QQ06"",
                        ""AA"": ""QQ"",
                        ""CC"": ""QQ""
                      }
                    ]
                  },
                  {
                    ""SPECIAL"": ""QQ07"",
                    ""AA"": ""QQ"",
                    ""CC"": ""QQ"",
                    ""DD"": ""QQ"",
                    ""Data7"": [
                      {
                        ""SPECIAL"": ""QQ08"",
                        ""AA"": ""QQ"",
                        ""CC"": ""QQ"",
                        ""Data8"": [
                          {
                            ""SPECIAL"": ""QQ09"",
                            ""AA"": ""QQ"",
                            ""BB"": ""QQ"",
                            ""CC"": ""QQ""
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  ""Data9"":
  {
    ""SPECIAL"": ""QQ10"",
    ""AA"": ""QQ"",
    ""BB"": ""QQ"",
    ""CC"": ""QQ"",
    ""Data10"":
    {
        ""SPECIAL"": ""QQ11"",
        ""AA"": ""QQ"",
        ""BB"": ""QQ"",
        ""CC"": ""QQ"",
        ""Data11"":
        {
            ""SPECIAL"": ""QQ12"",
            ""AA"": ""QQ"",
            ""BB"": ""QQ"",
            ""CC"": ""QQ""                  
        }
    }
  }
}";

            List<JObject> list = 
                JObject.Parse(json)
                .Descendants()
                .Where(jt => jt.Type == JTokenType.Property && ((JProperty)jt).Value.HasValues)
                .Cast<JProperty>()
                .Select(prop =>
                {

                    var parentName = prop.Ancestors()
                                         .Where(jt => jt.Type == JTokenType.Property)
                                         .Select(jt => ((JProperty)jt).Name)
                                         .FirstOrDefault();
                    var obj = new JObject(new JProperty("Current Property", prop.Name));

                    obj.Add(new JProperty("Immediate Ancestor Property Name", parentName ?? ""));


    // HERE***  (Question 2)
                    // here I would like to be able to add a new JObject property (just like I do above with "Parent")
                    // but this time I want to add the property values for Item1 and Item2 for a specific ancestor. 
                    // To achieve this, I want to grab all of the properties for an ancestor.

                    return obj;
                })
                .ToList();


            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine("list[" + i + "]:");
                Console.WriteLine(list[i].ToString(Formatting.None));
                Console.WriteLine();
            }
        }
    }
4

1 回答 1

1

听起来好像您想要JProperty其值不是数组或只有一个项目的数组的最低父级。如果是这样,你可以这样做:

var list = 
    JObject.Parse(json)
    .Descendants()
    .OfType<JProperty>()
    .Where(prop => prop.Value.HasValues)
    .Select(prop =>
    {

        var parentName = prop.Ancestors()
                             .OfType<JProperty>()
                             .Where(p => !(p.Value is JArray && ((JArray)p.Value).Count > 1))
                             .Select(p => p.Name)
                             .FirstOrDefault();
        var obj = new JObject(new JProperty("Current Property", prop.Name));

        obj.Add(new JProperty("Immediate Ancestor Property Name", parentName ?? ""));


        return obj;
    })
    .ToList();

这给出了所需的父列表。原型小提琴

于 2016-10-29T02:39:36.153 回答