加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 同一模式下的两个同名属性.尝试检索属性值时出错

发布时间:2020-12-16 02:03:08 所属栏目:百科 来源:网络整理
导读:我试图递归运行Json文件并检索名为“fileName”的属性,然后将该属性的值添加到ListView.但问题是,正如标题所说,同一模式中有两个相同属性的实例,这就是我认为导致错误的原因. 我想忽略包含“spigot.jar”的“fileName”属性,并仅检索包含“spigot-1.7.10-R0.
我试图递归运行Json文件并检索名为“fileName”的属性,然后将该属性的值添加到ListView.但问题是,正如标题所说,同一模式中有两个相同属性的实例,这就是我认为导致错误的原因.

我想忽略包含“spigot.jar”的“fileName”属性,并仅检索包含“spigot-1.7.10-R0.1-SNAPSHOT.jar”的属性.

我试图解析的Json示例(或使用http://ci.md-5.net/job/Spigot/api/json?depth=1作为参考):

"artifacts" : [
    {
      "displayPath" : "spigot-1.7.10-R0.1-SNAPSHOT.jar","fileName" : "spigot-1.7.10-R0.1-SNAPSHOT.jar","relativePath" : "Spigot-Server/target/spigot-1.7.10-R0.1-SNAPSHOT.jar"
    },{
      "displayPath" : "spigot.jar","fileName" : "spigot.jar","relativePath" : "Spigot-Server/target/spigot.jar"
    }
  ]

我如何尝试解析,并将其添加到C#中的ListView:

var url = "http://ci.md-5.net/job/Spigot/api/json?depth=1";
var content = (new WebClient()).DownloadString(url);

dynamic json = JsonConvert.DeserializeObject(content);

foreach (var builds in json.builds)
{
    string fileName = builds.artifacts.fileName;

    lvServers.Items.Add(fileName);
}

我该如何成功检索“fileName”属性?

解决方法

请尝试以下方法.这将列出构建号加上每个构建的第一个文件名:

var url = "http://ci.md-5.net/job/Spigot/api/json?depth=1";
var content = (new WebClient()).DownloadString(url);

JObject root = JObject.Parse(content);

var list = root["builds"].Select(b => 
           b["number"].ToString() + " - " + 
           b["artifacts"].Select(a => a["fileName"].ToString())
                         .FirstOrDefault());

foreach (var fileName in list)
{
    lvServers.Items.Add(fileName);
}

演示:https://dotnetfiddle.net/54l8YX

请注意,构建#1603没有工件(我猜是因为该构建的结果是FAILURE)所以文件名为空.

解释上面代码中发生了什么

我正在使用Json.Net的LINQ-to-JSON API(JObjects,JTokens,JArrays等)与System.Linq名称空间(Select,FirstOrDefault)和几个lambda expressions中的内置.NET扩展方法相结合,从JSON层次结构中提取数据.

这是它如何分解:

>我首先使用JObject.Parse(内容)将下载的内容解析为JObject.
>使用JObject,我可以使用方括号语法(就像词典一样)来获取该对象中的直接子属性的值. root [“builds”]给了我一个代表构建列表的JOA的JArray.
> Select方法允许我获取某个东西的IEnumerable(在这种情况下是表示构建的JObject的JArray),迭代该列表并将一个函数应用于列表中的每个项目,以便将其转换为其他内容的列表(在这种情况下是字符串列表).
>我应用于每个构建JObject的函数是lambda expression:b => b [“number”]“ – ”b [“artifacts”] ….在这个表达式中我说“从构建b,将number属性作为字符串,用分隔符连接 – 和子表达式从构建的工件列表中获取第一个文件名.
>在子表达式中,我获取构建的artifacts属性的值(这是JObjects的另一个JArray),然后使用Select on将其转换为具有lambda表达式a =>的文件名列表.一个[文件名]的ToString().但是,因为我只想要第一个fileName,所以我使用FirstOrDefault()来将列表剔除到单个项目(如果没有项目则为null).

希望这是有道理的.如果您不熟悉LINQ或lambda表达式,那么代码肯定会有点神秘.下面是一个不使用这些结构的替代版本,但完全相同.理解它可能会容易一些.

var url = "http://ci.md-5.net/job/Spigot/api/json?depth=1";
var content = (new WebClient()).DownloadString(url);

JObject root = JObject.Parse(content);

foreach (JObject build in root["builds"])
{
    string buildName = build["number"].ToString() + " - ";

    foreach (JObject artifact in build["artifacts"])
    {
        JToken fileName = artifact["fileName"];
        if (fileName != null)
        {
            buildName += fileName.ToString();   
        }
        break;
    }

    lvServers.Items.Add(buildName);
}

演示:https://dotnetfiddle.net/vwebrY

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读