NewtonSoft.JSON官方手册中文版【连载18】

配合LINQ查询JSON

LINQ to JSON提供了很多方法,用来从它的对象中读取数据。JObject/JArray上的索引方法让你能够依靠它在对象上的属性名称或集合中的索引来快速取得数据,而Children()让你能够把数据的范围读取为 IEnumerable<JToken>,然后利用LINQ来查询。

  • 通过属性名称或集合索引来取得值
  • 利用LINQ查询

通过属性名称或集合索引来取得值

从LINQ to JSON取得值的最简单方法是使用JObject/JArray上的Item[Object]索引,然后把返回的JValue强制转换为你想要的类型。

取得JSON值

string json = @"{
  'channel': {
  'title': 'James Newton-King',
  'link': 'http://james.newtonking.com',
  'description': 'James Newton-King\'s blog.',
  'item': [
    {
      'title': 'Json.NET 1.3 + New license + Now on CodePlex',
      'description': 'Announcing the release of Json.NET 1.3, the MIT license and the source on CodePlex',
      'link': 'http://james.newtonking.com/projects/json-net.aspx',
      'categories': [
        'Json.NET',
        'CodePlex'
      ]
    },
    {
      'title': 'LINQ to JSON beta',
      'description': 'Announcing LINQ to JSON',
      'link': 'http://james.newtonking.com/projects/json-net.aspx',
      'categories': [
        'Json.NET',
        'LINQ'
      ]
    }
  ]
  }
}";
JObject rss = JObject.Parse(json);
string rssTitle = (string)rss["channel"]["title"];
// James Newton-King
string itemTitle = (string)rss["channel"]["item"][0]["title"];
// Json.NET 1.3 + New license + Now on CodePlex
JArray categories = (JArray)rss["channel"]["item"][0]["categories"];
// ["Json.NET", "CodePlex"]
IList<string> categoriesText = categories.Select(c => (string)c).ToList();
// Json.NET
// CodePlex

利用LINQ查询

还可以利用LINQ查询JObject/JArray。Children()将JObject/JArray的子元素值返回为一个IEnumerable<JToken>,然后可以利用标准的WHERE/OrderBy/Select LINQ运算符来查询了。

 Note
Children()返回口令的所有子元素。如果它是一个JObject,则将返回一个要处理的属性的集合,如果它是JArray,你将取得数组值的集合。

查询JSON

var postTitles =
  from p in rss["channel"]["item"]
  select (string)p["title"];
foreach (var item in postTitles)
{
  Console.WriteLine(item);
}
//LINQ to JSON beta
//Json.NET 1.3 + New license + Now on CodePlex
var categories =
  from c in rss["channel"]["item"].SelectMany(i => i["categories"]).Values<string>()
  group c by c
  into g
  orderby g.Count() descending
  select new { Category = g.Key, Count = g.Count() };
foreach (var c in categories)
{
  Console.WriteLine(c.Category + " - Count: " + c.Count);
}
//Json.NET - Count: 2
//LINQ - Count: 1
//CodePlex - Count: 1

LINQ to JSON还可以用来手工把JSON转换为.NET对象。

利用LINQ对象反序列化

public class Shortie
{
  public string Original { get; set; }
  public string Shortened { get; set; }
  public string Short { get; set; }
  public ShortieException Error { get; set; }
}
public class ShortieException
{
  public int Code { get; set; }
  public string ErrorMessage { get; set; }
}

当你在操作JSON时,如果它并不严密匹配你的.NET对象,则在.NET对象之间手工序列化和反序列化是很有用的。

利用LINQ反序列化的示例

string jsonText = @"{
  'short': {
  'original': 'http://www.foo.com/',
  'short': 'krehqk',
  'error': {
    'code': 0,
    'msg': 'No action taken'
  }
  }
}";
JObject json = JObject.Parse(jsonText);
Shortie shortie = new Shortie
{
  Original = (string)json["short"]["original"],
  Short = (string)json["short"]["short"],
  Error = new ShortieException
  {
      Code = (int)json["short"]["error"]["code"],
      ErrorMessage = (string)json["short"]["error"]["msg"]
  }
};
Console.WriteLine(shortie.Original);
// http://www.foo.com/
Console.WriteLine(shortie.Error.ErrorMessage);
// No action taken

 利用SelectToken查询JSON

SelectToken()提供了利用单个字符串路径到想要的JToken来查询LINQ to JSON的方法。SelectToken使动态查询变得很容易,因为整个查询是定义在字符串中的。

  • SelectToken
  • SelectToken with JSONPath
  • SelectToken with LINQ

SelectToken

SelectToken是JToken上的一种方法,取用一个到子口令的字符串路径。SelectToken返回该子口令,或者返回null引用,如果在那个路径的位置没有找到口令的话。

路径是由属性的名称、数组的索引构成,由点号隔开,例如,Manufacturers[0].Name。

SelectToken示例

JObject o = JObject.Parse(@"{
  'Stores': [
  'Lambton Quay',
  'Willis Street'
  ],
  'Manufacturers': [
  {
    'Name': 'Acme Co',
    'Products': [
      {
        'Name': 'Anvil',
        'Price': 50
      }
    ]
  },
  {
    'Name': 'Contoso',
    'Products': [
      {
        'Name': 'Elbow Grease',
        'Price': 99.95
      },
      {
        'Name': 'Headlight Fluid',
        'Price': 4
      }
    ]
  }
  ]
}");
string name = (string)o.SelectToken("Manufacturers[0].Name");
// Acme Co
decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price");
// 50
string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name");
// Elbow Grease

SelectToken配合JSONPath

SelectToken支持JSONPath查询。在此处进一步了解JSONPath。

SelectToken配合JSONPath

JObject o = JObject.Parse(@"{
  'Stores': [
  'Lambton Quay',
  'Willis Street'
  ],
  'Manufacturers': [
  {
    'Name': 'Acme Co',
    'Products': [
      {
        'Name': 'Anvil',
        'Price': 50
      }
    ]
  },
  {
    'Name': 'Contoso',
    'Products': [
      {
        'Name': 'Elbow Grease',
        'Price': 99.95
      },
      {
        'Name': 'Headlight Fluid',
        'Price': 4
      }
    ]
  }
  ]
}");
// manufacturer with the name 'Acme Co'
JToken acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");
Console.WriteLine(acme);
// { "Name": "Acme Co", Products: [{ "Name": "Anvil", "Price": 50 }] }
// name of all products priced 50 and above
IEnumerable<JToken> pricyProducts = o.SelectTokens("$..Products[?(@.Price >= 50)].Name");
foreach (JToken item in pricyProducts)
{
  Console.WriteLine(item);
}
// Anvil
// Elbow Grease

SelectToken配合LINQ

SelectToken可以与标准LINQ方法结合使用。

SelectToken配合LINQ的示例

IList<string> storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList();
// Lambton Quay
// Willis Street
IList<string> firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList();
// null
// Headlight Fluid
decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price"));
// 149.95
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值