如何使用 SelectTokens 查询多个字段?

How to query multiple fields with SelectTokens?

如果我有一个 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 它们,但这行得通吗?两个结果数组是否保证保留原始源数据的顺序?有没有一种更简单的方法可以只用一个查询来完成?

您可以使用联合运算符 ['Name','Address'] 来同时 select 多个属性的值。但是,在某些时候,您将需要生成仅包含所需属性的 新对象,例如通过父对象对它们进行分组:

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 查询,但感觉有点过于复杂。我建议只 selecting 对象,然后使用嵌套查询来获取所需的属性,如下所示:

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

演示 fiddle here.