簡體   English   中英

如何從指定級別獲取json節點?

[英]How can i get a json node from a specified level?

我有這個json:

 {  
   "treeview":[  
      {  
         "text":"blah",
         "nodes":[  

         ]
      },
      {  
         "text":"blah",
         "nodes":[  

         ]
      },
      {  
         "text":"blah",
         "nodes":[  
            {  
               "text":"blah",
               "nodes":[  
                  {  
                     "text":"foo",
                     "nodes":[  
                         // I need to put data in here !!!
                     ]
                  }
               ]
            }
         ]
      },
      {  
         "text":"blah",
         "nodes":[  

         ]
      },
      {  
         "text":"foo",
         "nodes":[  
             // Not here !
         ]
      }
   ]
}

我需要將值放在我位於第2級的 “節點”元素上,並且“文本”等於“ foo”。

到目前為止,這是我嘗試過的方法:

var json = myJson;
// First approach
var selector = (JArray)json.SelectTokens($"$..treeview[?(@.text == 'foo')]");
// Second approach
var selector2 = (JArray)json.SelectToken($"$.treeview[?(@...text == 'foo')]");

selector.Add(new JObject(new JProperty("text", "myValue"));

我不了解查詢中的“點”是如何工作的……我只知道當您鍵入2個“點”時,它會瀏覽整個JSON……是否有只查詢特定縮進級別的方法?

我想通了,是的,當我們要查詢純文本格式的json時,我們可以指定級別縮進,方法如下:

var json = myJson;
var selector = (JArray)json.SelectTokens($"$.treeview[*].nodes[*].nodes[(@.text =='foo')].nodes");
selector.Add(new JObject(new JProperty("text", "myValue")));

您可以在這里進行測試: http : //jsonpath.com/

復制過去的json示例,並將其添加到jsonPath中: $.treeview[*].nodes[*].nodes[*].text

這樣就可以在所需的"level of identation" 'foo'獲取'foo'值,而無需在數組中指定任何索引,只需使用此'*'而不是int

使用對象比僅使用純json文本要容易得多...

使用Newtonsoft.Json包...

class Program
{
    static void Main(string[] args)
    {
        var jsonstring = "{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\", \"nodes\": []}, {\"text\":\"bar\", \"nodes\": []}, {\"text\":\"foo\", \"nodes\": []}]}";

        //This is the root node
        var firstLevelNodes = JsonConvert.DeserializeObject<Node>(jsonstring);

        //All the nodes in the root nodes node collection
        var secondLevelNodes = firstLevelNodes.nodes;

        //All of the nodes in the collections of the second level nodes
        var thirdLevelNodes = secondLevelNodes.SelectMany(sln => sln.nodes);


        Console.WriteLine("First Level Nodes: \n" + JsonConvert.SerializeObject(firstLevelNodes).PrettyPrint());
        Console.WriteLine();
        Console.WriteLine("Second Level Nodes: \n" + JsonConvert.SerializeObject(secondLevelNodes).PrettyPrint());
        Console.WriteLine();
        Console.WriteLine("Third Level Nodes: \n" + JsonConvert.SerializeObject(thirdLevelNodes).PrettyPrint());

        secondLevelNodes.First().nodes = new List<Node> { new Node { text = "new node" , nodes = new List<Node>() } };

        Console.WriteLine();
        Console.WriteLine("Third Level Nodes (with new node): \n" + JsonConvert.SerializeObject(thirdLevelNodes).PrettyPrint());

        Console.ReadLine();
    }
}

public static class JSONExtensions
{
    public static string PrettyPrint(this string json)
    {
        dynamic parsedJson = JsonConvert.DeserializeObject(json);
        return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
    }

}


[Serializable]
public class Node
{
    public string text { get; set; }
    public IEnumerable<Node> nodes { get; set; }
}

輸出:

First Level Nodes:
{
  "text": "blah",
  "nodes": [
    {
      "text": "foo",
      "nodes": []
    },
    {
      "text": "bar",
      "nodes": []
    },
    {
      "text": "foo",
      "nodes": []
    }
  ]
}

Second Level Nodes:
[
  {
    "text": "foo",
    "nodes": []
  },
  {
    "text": "bar",
    "nodes": []
  },
  {
    "text": "foo",
    "nodes": []
  }
]

Third Level Nodes:
[]

Third Level Nodes (with new node):
[
  {
    "text": "new node",
    "nodes": []
  }
]

編輯:

因此,如果您只想使用帶有文本foo的第二級節點,則只需使用..

var secondLevelFooNodes = secondLevelNodes.Where(sln=>sln.text == "foo");
//then use these nodes

編輯2:

使用實際的JSON對象也需要TreeView類。

class Program
{
    static void Main(string[] args)
    {
        var jsonstring = "{\"treeview\":[{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\",\"nodes\":[]}]}]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"foo\",\"nodes\":[]}]}";

        //This is the root node
        var treeView = JsonConvert.DeserializeObject<TreeView>(jsonstring);

        //All the nodes in the root nodes node collection
        var firstLevelNodes = treeView.treeview;

        //All of the nodes in the collections of the first level nodes
        var secondLevelNodes = firstLevelNodes.SelectMany(fln => fln.nodes);

        //All of the nodes in the collections of the second level nodes
        var thirdLevelNodes = secondLevelNodes.SelectMany(sln => sln.nodes);

        Console.WriteLine("The TreeView: \n" + JsonConvert.SerializeObject(treeView, Formatting.Indented));

        thirdLevelNodes.First(sln => sln.text == "foo").nodes = new List<Node> { new Node { text = "new node", nodes = new List<Node>() } };

        Console.WriteLine();
        Console.WriteLine("The TreeView (with new node): \n" + JsonConvert.SerializeObject(treeView, Formatting.Indented));

        Console.ReadLine();
    }
}

[Serializable]
public class Node
{
    public string text { get; set; }
    public IEnumerable<Node> nodes { get; set; }
}

[Serializable]
public class TreeView
{
    public IEnumerable<Node> treeview { get; set; }
}

輸出:

The TreeView:
{
  "treeview": [
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "blah",
      "nodes": [
        {
          "text": "blah",
          "nodes": [
            {
              "text": "foo",
              "nodes": []
            }
          ]
        }
      ]
    },
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "foo",
      "nodes": []
    }
  ]
}

The TreeView (with new node):
{
  "treeview": [
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "blah",
      "nodes": [
        {
          "text": "blah",
          "nodes": [
            {
              "text": "foo",
              "nodes": [
                {
                  "text": "new node",
                  "nodes": []
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "text": "blah",
      "nodes": []
    },
    {
      "text": "foo",
      "nodes": []
    }
  ]
}

您需要指定“節點”數組的正確路徑。 嘗試這個:

JObject json = JObject.Parse("{\"treeview\":[{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\",\"nodes\":[]}]}]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"foo\",\"nodes\":[]}]}");
JArray array = (JArray)json.SelectToken("treeview[2].nodes[0].nodes[0].nodes");
array.Add(new JObject(new JProperty("text", "myValue")));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM