如果我有一个JSON数组,并且想从每个对象中提取一个字段,那就很简单了:
Data:
{
"Values": [
{
"Name": "Bill",
"Age": "25",
"Address": "1234 Easy St."
},
{
"Name": "Bob",
"Age": "28",
"Address": "1600 Pennsylvania Ave."
},
{
"Name": "Joe",
"Age": "31",
"Address": "653 28th St NW"
}
]
}
Query:
data.SelectTokens("Values[*].Name")
这将为我提供所有名称的数组。但是,如果我想要多个领域怎么办?有没有办法获取包含名称和地址的对象数组?
一种明显的方法是先运行两次SelectTokens
,然后再运行Zip
,但这行得通吗?是否保证两个结果数组都能保留原始源数据的顺序?有没有一种更简单的方法可以只执行一个查询呢?
答案 0 :(得分:2)
您可以使用联合运算符['Name','Address']
来同时选择多个属性的值。但是,在某些时候,您将需要生成仅包含所需属性的新对象,例如,通过将它们按父对象分组:
var query = data.SelectTokens("Values[*]['Name','Address']")
.Select(v => (JProperty)v.Parent) // Get parent JProperty (which encapsulates name as well as value)
.GroupBy(p => p.Parent) // Group by parent JObject
.Select(g => new JObject(g)); // Create a new object with the filtered properties
虽然此方法有效并且仅使用一个JSONPath查询,但感觉有点过于复杂。我建议只选择对象,然后使用嵌套查询来获取所需的属性,如下所示:
var query = data.SelectTokens("Values[*]")
.OfType<JObject>()
.Select(o => new JObject(o.Property("Name"), o.Property("Address")));
或者也许
var query = data.SelectTokens("Values[*]")
.Select(o => new JObject(o.SelectTokens("['Name','Address']").Select(v => (JProperty)v.Parent)));
演示小提琴here。