使用Linq查询复杂的Json

本文关键字:Json 复杂 查询 Linq 使用 | 更新日期: 2023-09-27 17:53:38

我想在json字符串中进行Linq查询。

关于我正在做的事情的一点信息。在工作中,我们有一个基于网页的时间表系统,它不支持windows 8和windows phone 8应用程序,这就是我决定做一个的原因。使用HttpClient,我得到一个http字符串,然后我转换为xml,然后Json。正如您可以从下面的链接中看到的,'TheWholeJsonString。json'文件)属性名称和json对象名称不提供信息,json文件复杂。这就是为什么我决定从JSON字符串中提取一些值,并编写一个全新的JSON文件,其中包含以更翔实的方式提取的JSON值。

原始JSON文件中的[tr]数组有几个JSON对象。在'VeryShorten。你可以看到其中一个对象的结构(OBS!)有不同结构的物体)。我唯一隐藏的是RL ppl的名字和电子邮件地址。

我还附上了'ShortenVersion '。Json ',这只是整个Json字符串的缩短版本,只是为了便于处理。

Json数据样本
{
    "@class": "odd",
    "td": [
      {
        "@class": "user",
        "@onmouseover": "userInfo('149');",
        "@onmouseout": "userInfo(0);",
        "@onmousemove": "moveSlotInfo();",
        "#text": " ",
        "a": {
          "@href": "Name3@dreamnet.com",
          "#text": "Name3"
        }
      },
      .
      .
      .

在c#中,如果我尝试以下代码(不是Linq)

var jObject = JObject.Parse(jString); //jString is 'TheWholeJsonString.json' file in the attached link
var jObj = jObject["tbody"]["tr"][8];
var gh = jObj.Value<JToken>("td").Children().First().Value<JToken>("a").Value<string>("#text");

我可以得到'#text'的值是*'Name3'。

然而,如果我尝试以下代码(Linq版本):-

var jObject = JObject.Parse(jString);
var jCollection = jObject["tbody"]["tr"].Children();
var test = from userToken in jCollection
            where
                userToken.Value<JToken>("td")
                    .Children()
                    .First()
                    .Value<JToken>("a")
                    .Value<string>("#text")
                    .Contains("Name3")
            select (string)userToken["#text"];
foreach (var item in test)
{
   var fgh = item.Type;
}

它将在foreach循环的第一次迭代时中断,并出现以下错误消息"Cannot access child value on Newtonsoft.Json.Linq.JValue"。我确实知道是什么原因造成这个问题,但我不知道怎样解决它。问题是,并不是jCollection中的每个令牌都有一个'td'对象,即使令牌有'td'对象,它也不总是有令牌'a'。你可以在TheWholeJsonString中看到这个。'或'ShortVersion. json'。Json '文件,我附加在链接中。希望这将解释更多信息。

所以问题是:-谁可以帮助解决这个问题?

使用Linq查询复杂的Json

您可以使用SelectTokens方法。注意false作为第二个参数-如果没有找到元素,不要产生错误。

var jObject = JObject.Parse(jString);
var trList = jObject["tbody"]["tr"];
string[] names = trList.SelectMany(tr => tr.SelectTokens("td[0].a.#text", false))
                       .Select(t => t.Value<string>())
                       .ToArray();

您可以像这样轻松地使用LINQ进行查询

考虑到这个JSON

{
    "items": [
        {
            "id": "10",
            "name": "one"
        },
        {
            "id": "12",
            "name": "two"
        }
    ]
}

将其放入变量json中,像这样,

JObject json = JObject.Parse("{'items':[{'id':'10','name':'one'},{'id':'12','name':'two'}]}");

您可以使用以下LINQ查询从名称为"one"的项中选择所有id

var Ids =
    from item in json["items"]
    where (string)item["name"] == "one"
    select item["id"];