Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从分层JSON中挑选简单属性_C#_Json.net - Fatal编程技术网

C# 从分层JSON中挑选简单属性

C# 从分层JSON中挑选简单属性,c#,json.net,C#,Json.net,*尽管其他用户对我的标题进行了编辑,但我正在寻找一种使用C#**中JSON.NET库的解决方案。 包含psuedocode的回复很好!:) 我正在尝试使用JSON数据集提供的分层数据。我正在使用C#和JSON.NET。如果有帮助的话,我愿意在一般情况下使用Linq,特别是在JSON.NET中使用Linq;否则,使用非Linq C#/JSON.NET就可以了 理想情况下,我正努力优雅地完成两件事: 我想提取表示每个分支及其自身属性的JSON,而不是它的子(嵌套)分支对象(稍后我将进一步解释) 我希

*尽管其他用户对我的标题进行了编辑,但我正在寻找一种使用C#**中JSON.NET库的解决方案。

包含psuedocode的回复很好!:)

我正在尝试使用JSON数据集提供的分层数据。我正在使用C#和JSON.NET。如果有帮助的话,我愿意在一般情况下使用Linq,特别是在JSON.NET中使用Linq;否则,使用非Linq C#/JSON.NET就可以了

理想情况下,我正努力优雅地完成两件事:

  • 我想提取表示每个分支及其自身属性的JSON,而不是它的子(嵌套)分支对象(稍后我将进一步解释)

  • 我希望在创建分支对象时跟踪父节点

  • 如需进一步考虑,请参考以下JSON摘录:

    {
      "Branch1": {
        "Prop1A" : "1A",
        "Prop1B" : "1B",
        "Prop1C" : "1C",
        "Branch2" : {
          "Prop2A" : "2A",
          "Prop2B" : "2B",
          "Prop2C" : "2C",
          "Branch3" : {
            "Prop3A" : "3A",
            "Prop3B" : "3B",
            "Prop3C" : "3C"
          }
        }
      }
    }
    
    与目标1相关(从上面): 给定由嵌套JSON对象组成的JSON,我只想为每个分支挑选简单(字符串)属性。例如,我想提取Branch1的JSON,它只包含Prop1A、Prop1B和Prop1C属性。然后我想提取Branch2的JSON,该JSON只包含Prop2A、Prop2B和Prop2C属性等。我意识到我可以将整个JSON表示为一个JSON.NET JToken对象,然后遍历其子对象()并只查找JTokenType.Property类型,但是,也许有一种更优雅的方法可以使用Linq快速选择属性类型。。。?最后,我将有三个单独的JSON对象,如下所示:

    {
      "Prop1A" : "1A",
      "Prop1B" : "1B",
      "Prop1C" : "1C",
      "Parent" : ""
    }
    
    JSON对象1:

    {
      "Prop1A" : "1A",
      "Prop1B" : "1B",
      "Prop1C" : "1C"
    }
    
    JSON对象2:

    {
      "Prop2A" : "2A",
      "Prop2B" : "2B",
      "Prop2C" : "2C"
    }
    
    JSON对象3:

    { “Prop3A”:“3A”, “Prop3B”:“3B”, “Prop3C”:“3C” }

    与目标2相关(从上面): 理想情况下,上面提取的每个JSON也会有一个属性指示其父级。因此,最终的JSON对象如下所示:

    {
      "Prop1A" : "1A",
      "Prop1B" : "1B",
      "Prop1C" : "1C",
      "Parent" : ""
    }
    
    以及:

    以及:

    有什么想法吗?

    您可以使用它来查找JSON层次结构中的所有对象,然后对于每个对象,循环遍历它的对象,并过滤掉那些属于原语的对象。因此,以下查询将创建一个
    列表
    ,其中包含所需的属性名称和值:

    var root = (JContainer)JToken.Parse(jsonString);
    
    var query1 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
                 let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
                 where l.Any()                                              // Skip objects with no properties
                 select new JObject(l);                                     // And return a JObject
    
    var list1 = query1.ToList();
    
    可以使用以下方法增强查询,以包括一个合成的“父”属性,该属性给出包含对象的直接父属性的名称:

    生成以下输出,显示
    JObject
    列表包含您需要的内容:

    var root = (JContainer)JToken.Parse(jsonString);
    
    var query1 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
                 let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
                 where l.Any()                                              // Skip objects with no properties
                 select new JObject(l);                                     // And return a JObject
    
    var list1 = query1.ToList();
    

    请注意,如果JSON对象本身有一个名为
    “Parent”
    的属性,那么
    JObject
    构造函数可能会抛出一个重复的键异常。

    为什么
    “Branch1”
    不是第一个
    “Prop1A”
    对象的父对象?这毕竟是直接的父属性名称,因为本例中的JSON表示JSON对象的父子层次关系。在本例中,对象1位于对象2的父对象中,对象2是对象3的父对象。对象1映射到Branch1(一个JSON对象,没有父对象,只有一个子分支——分支2);对象2映射到Branch2(一个JSON对象,其父对象为Branch1,子对象为Branch3);对象3映射到Branch3(一个JSON对象,其父对象为Branch2,没有子分支)。值得赞赏——但需要不同/独立的JSON对象与算法,不尝试重新构造现有JSON,而是尝试将原始JSON分解为多个更小的JSON对象,通过与父对象的链接保留层次结构。请参阅对原帖子的澄清。抱歉,可能没有让请求更清楚。还有,爱后代和自己()。谢谢你。我不知道你说的通过链接到家长来保留层次结构是什么意思。Linq到JSON中的父/子关系是双向的,因此,如果子对象“链接”到父对象,则父对象必须具有引用子对象的属性,这不是您在问题中显示的属性。另外,你只是想得到一个
    JObject
    对象列表,而不是一个字典列表吗?当然,公平的问题是:最终,这些JSON对象将成为C#对象。Branch1将是一个表示Windows GUI控件容器(例如表单控件)的对象;Branch2将是窗体内的容器对象(例如面板);Branch3将是面板内的一个控件。我只知道控件的父对象就足够了。JObject对象列表就可以了,其中[0]有分支1,[1]有分支2,等等。谢谢。@Jazimov-answer被修改为返回JObjectsSplendid列表!太感谢你了!如果可以,请提供除在线JSON.NET文档之外的任何关于掌握Linq for JSON.NET的参考资料,我发现这很难使用/理解。。。
                 let l = o.Properties().Where(p => p.Value.Type == JTokenType.String)       // Select their string-valued properties
    
    var query2 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
                 let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
                 where l.Any()                                              // Skip objects with no properties
                 // Add synthetic "Parent" property
                 let l2 = l.Concat(new[] { new JProperty("Parent", o.Ancestors().OfType<JProperty>().Select(a => a.Name).FirstOrDefault() ?? "") })
                 select new JObject(l2);                                    // And return a JObject.
    
    var list2 = query2.ToList();
    
    var query3 = from o in root.DescendantsAndSelf().OfType<JObject>()      // Find objects
                 let l = o.Properties().Where(p => p.Value is JValue)       // Select their primitive properties
                 where l.Any()                                              // Skip objects with no properties
                 // Add synthetic "Parent" property
                 let l2 = l.Concat(new[] { new JProperty("Parent", o.Ancestors().OfType<JProperty>().Skip(1).Select(a => a.Name).FirstOrDefault() ?? "") })
                 select new JObject(l2);                                    // And return a JObject.
    
    var list3 = query3.ToList();
    
    Console.WriteLine(JsonConvert.SerializeObject(list3, Formatting.Indented));
    
    [
      {
        "Prop1A": "1A",
        "Prop1B": "1B",
        "Prop1C": "1C",
        "Parent": ""
      },
      {
        "Prop2A": "2A",
        "Prop2B": "2B",
        "Prop2C": "2C",
        "Parent": "Branch1"
      },
      {
        "Prop3A": "3A",
        "Prop3B": "3B",
        "Prop3C": "3C",
        "Parent": "Branch2"
      }
    ]