使用C#在JSON.NET中查找特定值

时间:2014-01-19 10:27:30

标签: c# json linq json.net

我一直在制作一个Minecraft发射器。我有一个很长的JSON文件,其中包含启动一个版本所需的所有库。此代码的示例:

{
  "id": "1.6.2",
  "time": "2013-08-06T14:00:00+03:00",
  "releaseTime": "2013-07-05T16:09:02+03:00",
  "type": "release",
  "minecraftArguments": "--username ${auth_player_name} --session ${auth_session} --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}",
  "libraries": [
    {
      "name": "net.sf.jopt-simple:jopt-simple:4.5"
    },
    {
      "name": "com.paulscode:codecjorbis:20101023"
    },

所以你可以看到有一个名为libraries的数组。我可以查询" name"中的值。使用foreach很好,但有时这发生在json:

{
  "name": "org.lwjgl.lwjgl:lwjgl:2.9.0",
  "rules": [
    {
      "action": "allow"
    },
    {
      "action": "disallow",
      "os": {
        "name": "osx",
        "version": "^10\\.5\\.\\d$"
      }
    }
  ]
},

正如您所看到的,内部有一个名为rules的数组。我需要在name内的os内找到rules的值。我尝试过的任何事情都会出现异常并且无法正常工作。这是我目前用于解析代码的代码:

    foreach (JToken lib in profilejsono["libraries"])
    {
        if ((lib["rules"][1]["os"].ToString() == "osx") || (lib["rules"][1]["os"].ToString() == "linux"))
        {
            availableLibs.Add(lib["name"].ToString());
        }
    }

代码的重点不是添加库,如果它适用于OSX或Linux(我稍后会添加该功能)。我该怎么做?

1 个答案:

答案 0 :(得分:1)

您的问题的一个可能解决方案是概括检查操作系统名称(并使其与规则节点深度无关)。我想你有一些库对象,因为你需要将JSON输入字符串反序列化为某个对象。以下代码仅为具有规则节点的库节点提供库名称, os 节点具有指定的名称:

JSON测试输入文件 lib1.json

{
  "name": "lib1",
  "rules": [
    {
      "action": "allow"
    },
    {
      "action": "disallow",
      "os": {
        "name": "windows",
        "version": "^10\\.5\\.\\d$"
      }
    }
  ]
}

JSON测试输入文件 lib2.json

{
  "name": "lib2",
  "rules": [
    {
      "action": "allow"
    },
    {
      "action": "disallow",
      "os": {
        "name": "osx",
        "version": "^10\\.5\\.\\d$"
      }
    }
  ]
}

JSON测试输入文件 lib3.json

{
  "name": "lib3",
  "rules": [
    {
      "action": "allow"
    },
    {
      "action": "disallow",
      "os": {
        "name": "linux",
        "version": "^10\\.5\\.\\d$"
      }
    }
  ]
}

JSON测试输入文件 lib4.json

{
  "name": "lib4",
  "rules": [
    {
      "action": "allow"
    },
    {
      "action": "disallow"
    }
  ]
}

描述节点的JSON帮助程序对象,用于反序列化JSON输入:

// helper classes describing the library object (for the JSON deserialization)
public class Library
{
    public String Name { get; set; }
    public Rules[] Rules { get; set; }
}

public class Rules
{
    public String Action { get; set; }
    public Os Os { get; set; }
}

public class Os
{
    public String Name { get; set; }
    public String Version { get; set; }
}

仅获取匹配库的代码:

var jsonInput = @"d:\temp\json.net\lib{0}.json";
try
{
    // load libraries / deserialize json
    var libraries = new List<Library>();
    Enumerable.Range(1, 4).ToList().ForEach(index => 
    {
        var json = File.ReadAllText(String.Format(jsonInput, index));
        libraries.Add(JsonConvert.DeserializeObject<Library>(json));
    });
    // OS names to check if present in the current rules
    var osNames = new List<String> { "osx", "linux" };
    // check each library
    foreach (var library in libraries)
    {
        // do we have rules?
        if (library.Rules.Length > 0)
        {
            // get all non-empty OS nodes
            var existingOsNodes = library.Rules.Where (r => r.Os != null).Select (r => r.Os).ToList();
            // check for allowed OS name
            var osIsPresent = existingOsNodes.Where (node => osNames.Contains(node.Name.ToLower())).Select (node => node.Name);
            if (osIsPresent.Any())
            {
                Console.WriteLine(library.Name);
            }
        }
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

四个给定输入文件的输出为:

lib2
lib3