我有一个Json"数据库",正在尝试使用Newtonsoft Json.Net LINQ从中提取内容。
目标是从包含在父数组项中的子数组项中提取属性。父数组中的项将由键属性选择。"outer"元素是一个包含一个条目的数组,"internal"元素是由两个父条目组成的数组,每个父条目都有一个"key"和一个子"items"数组。希望通过其key匹配内部父条目,然后将子数组中所有项的子"itemid"属性提取到IList中。
file at filePath contains:
{
"outer":
[
{
"inner":
[
{
"key": "AAA",
"items":
[
{ "itemid": "a1" }
]
},
{
"key": "BBB",
"items":
[
{ "itemid": "b1" },
{ "itemid": "b2" }
]
}
]
}
]
}
我认为提取查询看起来像下面所示,但无论是这个还是我尝试过的几十个变体都没有成功。在一些变体中,它似乎一直工作到最终选择正确的内部"项目",但当我试图挖掘出"项目ID"数组时,它就崩溃了有什么线索吗?如果需要的话,我愿意把它分成两个单独的查询。
public IList<string> FindMatchingItems(string filePath, string id)
{
JObject JsonLinq = JObject.Parse(File.ReadAllText(filePath));
return JsonLinq["outer"].First()["inner"].Children()
.First(inner => inner["key"].ToString() == id)
.Select(selected => selected["items"].Children()["itemid"].ToString())
.ToList();
}
void Query(string filePath)
{
var ayes = FindMatchingItems(filePath, "AAA");
// ayes contains [] { "a1" }
var bees = FindMatchingItems(filePath, "BBB");
// bees contains [] { "b1", "b2" }
}
我想这就是您想要的:
JsonLinq["outer"].First()["inner"]
.Where(innerItem => innerItem["key"].Value<string>() == id)
.SelectMany(innerItem => innerItem["items"]
.Select(itm => itm["itemid"].Value<string>()))
.ToList();
这里的关键是使用.SelectMany
将投影的itemid
展平为一个新列表。
您可以在C#中创建一个类,然后使用JsonConvert.DescializeObject()
C# class
public class Item
{
public string itemid { get; set; }
}
public class Inner
{
public string key { get; set; }
public List<Item> items { get; set; }
}
public class Outer
{
public List<Inner> inner { get; set; }
}
public class RootObject
{
public List<Outer> outer { get; set; }
}
然后你可以使用
public List<string> FindMatchingItems(string filePath, string id)
{
var json = File.ReadAllText(filePath);
var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
var result = rootObject.outer.First().inner.First(i => i.key == id).items.Select(item => item.itemid).ToList();
return result;
}