【问题标题】:Querying a complex Json with Linq使用 Linq 查询复杂的 Json
【发布时间】:2014-03-26 20:34:15
【问题描述】:

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

关于我正在尝试做什么的小信息。在工作中,我们有一个基于 Web 的日程安排系统,它不支持 windows 8 和 windows phone 8 应用程序。这就是为什么我决定做一个。使用 HttpClient 我得到一个 http 字符串,然后我将其转换为 xml,然后是 Json。 从(下面的链接,'TheWholeJsonString.json' 文件)可以看出,属性名称和 JSON 对象名称没有提供信息,而且 JSON 文件很复杂。这就是为什么我决定从 JSON 字符串中提取一些值并编写一个全新的 JSON 文件,该文件以更丰富的方式包含提取的 JSON 值。

原始 JSON 文件中的 [tr] 数组有多个 JSON 对象。在链接文件夹中的“VeryShorten.json”文件中,您可以看到其中一个对象的结构(OBS!有不同结构的对象)。我唯一隐藏的是 RL ppl 的姓名和电子邮件地址。

我还附加了“ShortenVersion.json”,它只是整个 json 字符串的缩短版本,只是为了便于处理。

Json data sample

{
    "@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 循环的第一次迭代中中断,并显示以下错误消息“无法访问 Newtonsoft.Json.Linq.JValue 上的子值”。我现在真的是什么导致了这个问题,但我不知道如何解决它。问题在于,并非 jCollection 中的每个标记都有一个“td”对象,即使该标记具有“td”对象,它也不是始终具有标记“a”。您可以在我附加在链接中的“TheWholeJsonString.json”或“ShortVersion.json”文件中看到这一点。 希望这能解释更多信息。

所以问题是:- 任何人都可以帮助解决这个问题?

【问题讨论】:

    标签: c# json linq json.net


    【解决方案1】:

    您可以使用 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();
    

    【讨论】:

      【解决方案2】:

      您可以像这样使用 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"];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-08
        • 2014-02-23
        • 1970-01-01
        相关资源
        最近更新 更多