Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用json.net和linq在json中查找模式_C#_Json_Linq_Json.net - Fatal编程技术网

C# 使用json.net和linq在json中查找模式

C# 使用json.net和linq在json中查找模式,c#,json,linq,json.net,C#,Json,Linq,Json.net,我正在搜索一个json文件,其结构如下: { "objects": [ { "name": "obj1", "state": { "type": 4, "childs": [ "state": { "type": 5,

我正在搜索一个json文件,其结构如下:

{
    "objects": [
        {    
        "name": "obj1",
            "state": {
                "type": 4,
                    "childs": [
                         "state": {
                              "type": 5,
                               ...
状态可以作为子级包含状态,直到达到任意级别。现在,我试图找到所有包含特定状态模式的对象,例如,状态4与子状态5与子状态2

到目前为止,我的代码是这样的

        JObject o = JObject.Parse(System.IO.File.ReadAllText(@"j.json"));

        var oObjects=
            from p in o["objects"]
            where (string)p["state"] == "4"
            select (string)p["name"];

如何扩展代码以查找任何级别上包含搜索模式的所有对象?

一个选项是将json转换为xml,然后使用xpath查询获取节点列表

        string json = System.IO.File.ReadAllText(@"j.json");
        XmlDocument document = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
        XmlNodeList nodes = document.SelectNodes("//name[../state[type[.=4] and childs/state[type[.=5] and childs/state[type[.=2]]]]]");
您可以为此使用:

var objects = o.SelectTokens("$.objects[?(@.state.type == 4 
                       && @.state.childs[*].state.type == 5)].name")
                    .Select(s => (string)s)
                    .ToList();

要使其适用于不确定级别,则需要使用如下递归方法:

void Main()
{
    var str = @"{
        ""objects"": [
            {
                ""name"": ""obj1"",
                ""state"": {
                    ""type"": 4,
                    ""childs"": [
                        {
                            ""state"": {
                                ""type"": 5
                            }
                        }
                    ]
                }
            }
        ]
    }";

    var obj = JObject.Parse(str);

    GetValidObjects(obj, new string[] { "4", "5" }); // Name list of valid objects
}
以及定义如下的帮助器方法:

public IEnumerable<string> GetValidObjects(JObject obj, IEnumerable<string> values)
{
    return obj["objects"]
        .Where(i => (string)i["state"]["type"] == values.First() && ContainsState((JArray)i["state"]["childs"], values.Skip(1)))
        .Select(i => (string)i["name"]);
}

public bool ContainsState(JArray childs, IEnumerable<string> values)
{
    if (childs == null)
    {
        return values.Count() == 0;
    }

    return childs.Any(i => (string)i["state"]["type"] == values.First() && ContainsState((JArray)i["state"]["childs"], values.Skip(1)));
}
public IEnumerable GetValidObjects(JObject对象,IEnumerable值)
{
返回对象[“对象”]
.Where(i=>(string)i[“state”][“type”]==values.First()&&containssState((JArray)i[“state”][“childs”],values.Skip(1)))
。选择(i=>(string)i[“name”]);
}
公共布尔包含状态(JArray childs,IEnumerable值)
{
if(childs==null)
{
返回值。Count()==0;
}
返回childs.Any(i=>(string)i[“state”][“type”]==values.First()&&containssState((JArray)i[“state”][“childs”],values.Skip(1));
}

查看递归。您可以尝试使用
递归下降运算符。看见了解这个助手方法也很好,但它不适用于除2之外的其他级别。