从分层JSON第二部分中挑出简单属性

时间:2016-07-27 02:54:28

标签: c# linq json.net

我认为这个问题可能是不正确的,所以我创建了一个"姐姐"这个具体的产出引用的问题更为重要。请参阅: Querying JSON Nested Arrays with Linq, JSON.NET, C# 如果这个问题在此之前得到解答,我会尝试使用其他问题的信息自己回答这个问题...... :)谢谢!

在上一个问题(Picking Out Simple Properties from Hierarchical JSON)中,我询问了如何从分层JSON中获取简单属性。那里的答案[在本文末尾粘贴为Linq查询]极其有用(并且,自从发布以来,我已经对Linq和JSON.NET进行了相当多的研究)。所以我没有使用这个论坛,因为我很懒 - 当我真的陷入困境时,我会使用它,似乎无法在我可以访问的书籍中找到答案。

我对如何继续上一个问题提供的示例感到困惑。这个问题建立在前一个问题的基础上,所以在这里(尽可能简洁地表达)是我喜欢在单个Linq查询中学习如何做的事情。

回顾一下:我正在使用这样的动态JSON(它比我之前的第一部分问题中提到的JSON更复杂,因为它包含数组):

{
    "Branch1": {
        "Prop1A": "1A",
        "Prop1B": "1B",
        "Prop1C": "1C",
        "Branch2": {
            "Prop2A": "2A",
            "Prop2B": "2B",
            "Prop2C": "2C",
            "Branch3": [{
                "Prop3A": "3A",
                "Prop3B": "3B",
                "Prop3C": "3C"
            }, {
                "Prop3D": "3D",
                "Prop3E": "3E",
                "Prop3F": "3F"
            }, {
                "Prop3G": "3G",
                "Prop3H": "3H",
                "Prop3I": "3I"
            }]
        },
        "Branch4": [{
            "Prop4A": "4A",
            "Prop4B": "4B",
            "Prop4C": "4C"
        }, {
            "Prop4E": "4E",
            "Prop4F": "4F",
            "Prop4G": "4G"
        }, {
            "Prop4H": "4H",
            "Prop4I": "4I",
            "Prop4I": "4I"
        }]
    }
}

如您所见,动态JSON由分层对象组成,这些对象是JSON对象,JSON数组和JSON属性。

最终,我想将此JSON转换为我可以在C#中使用的List对象。我计划使用该List对象从顶部向下按文档顺序有效地处理每个JSON分支。

List集合中的每个项目都是JObject;这些对象中的每一个都有一个合成的父母" string属性,它将指向JObject在原始JSON中出现的分支(下面的示例解释了我的意思" parent")。 [上一个问题正确地为这个"父母"提出了解决方案。价值,因此与这个问题不太相关......这里有什么新的/相关的是处理JSON中的JArray对象......]

关键是我希望每个List项对象只包含该对象的字符串值属性。例如,Branch1具有字符串属性Prop1A,1B和1C。因此,我希望query [0]包含:

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

接下来,我希望query [2]包含Branch2的字符串值属性:

{"Prop2A":"2A","Prop2B":"2B","Prop2C":"2C", Parent:"Branch1"}

接下来,我希望查询[2]只包含Branch3的字符串属性,但由于Branch3是一个对象数组,我希望该数组在查询[2]中一起结束:

[
 {"Prop3A": "3A","Prop3B": "3B","Prop3C": "3C"},
 {"Prop3D": "3D","Prop3E": "3E","Prop3F": "3F"},
 {"Prop3G": "3G","Prop3H": "3H","Prop3I": "3I"}
]

请注意,这个分支还没有引用它的" Parent" ...我很高兴在查询[2]中得到一个如上所示的数组。 (我计划使用dbc的逻辑为每个数组元素添加一个" Parent"属性,或者找出一种方法来创建一个包含该数组的新JObject并仅引用Parent一次): / p>

[{"Prop3A": "3A","Prop3B": "3B","Prop3C": "3C","Parent":"Branch2"},
 {"Prop3D": "3D","Prop3E": "3E","Prop3F": "3F","Parent":"Branch2"},
 {"Prop3G": "3G","Prop3H": "3H","Prop3I": "3I","Parent":"Branch2"}
]

所以,你可以看到: *我希望任何不是数组的JSON分支在查询结果中作为新的JObject插入,只需要它的字符串属性和对其父分支的引用。 *我希望任何作为数组的JSON分支作为新的JObject数组插入查询结果中,同时只需要它的字符串属性和对其父分支的引用。

我自己解决这个问题的麻烦在于弄清楚如何创建"如果myJsonObject是JArray" Linq中的条件,并且当分支不是数组时仅分配字符串属性属性,并且当它是JArray时迭代数组的元素。我怀疑我需要以某种方式利用? :三元表达,但我不知道该怎么做。

上一个问题的查询在这里:

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();

该代码不会以上述方式处理数组。

感谢您阅读!

1 个答案:

答案 0 :(得分:0)

这个问题的合适且更一般的答案有效地出现在我的相关帖子中: Picking Out Simple Properties from Hierarchical JSON