2016-08-24 85 views
3

我有一個以.json文件看起來像這樣:找到一個JSON項並添加一個嵌套元素

[ 
    { 
    "username": "John", 
    "currency": 8, 
    "pulls": 
    [ 
     { 
     "character": "person" 
     }, 
     { 
     "character": "loved one" 
     } 
    ] 
    }, 
    { 
    "username": "Mike", 
    "currency": 2, 
    "pulls": 
    [ 
     { 
     "character": "noone" 
     } 
    ] 
    }, 
    { 
    "username": "Clara", 
    "currency": 5,  
    "pulls": 
    [ 
     { 
     "character": "someone" 
     } 
    ] 
    } 
] 

我設法到目前爲止做的就是修改「貨幣」:

bool userExists = false; 
    string jsonPointsString = File.ReadAllText(userPath); 
    dynamic jsonObjects = JsonConvert.DeserializeObject(jsonPointsString); 
    foreach (var jsonObject in jsonObjects) 
    { 
     if (jsonObject["username"] == user) 
     { 
      jsonObject["currency"] += value; 
      string output = JsonConvert.SerializeObject(jsonObjects, Formatting.Indented); 
      File.WriteAllText(userPath, output); 
      userExists = true; 
     } 
    } 

以及從頭開始添加一個全新的條目:

JsonCollection.User user = new JsonCollection.User(); 
    user.username = username; 
    user.currency = 10; 
    using (StreamReader r = new StreamReader(userPath)) 
    { 
     string json = r.ReadToEnd(); 
     List<JsonCollection.User> users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(json); 
     users.Add(user); 
     newJson = JsonConvert.SerializeObject(users, Formatting.Indented); 
    } 
    File.WriteAllText(userPath, newJson); 

但是,無論我嘗試什麼,我都無法添加另一個元素來「拉」。這個想法是我用一個用戶名和一個拉,兩個字符串來調用一個函數。基於用戶名變量,我必須找到相應的Json Entry,並根據pull變量在「pulls」樹中創建一個新條目。這是我能想出:

public void AddPullToUser(string user, string newPull) 
    { 
     user = "Mike"; //test value 

     string jsonPointsString = File.ReadAllText(userPath); 
     dynamic jsonObjects = JsonConvert.DeserializeObject(jsonPointsString); 
     foreach (var jsonObject in jsonObjects) 
     { 
      if (jsonObject["username"] == user) 
      { 
       //jsonObject["pulls"] = newPull; 

       JsonCollection.Character pull = new JsonCollection.Character(); 
       pull.character = newPull; 
       jsonObject["pulls"] = pull; 

       string output = JsonConvert.SerializeObject(jsonObjects, Formatting.Indented); 
       File.WriteAllText(userPath, output); 

      } 
     } 
    } 

如果我做這樣的系統中的JsonCollection不能轉換爲JArray但不使用JArray我不知道如何找到特定用戶的樹。 在第二步中,這將不得不進一步擴展,以避免產生重複的「拉」,但首先這一切都必須工作。

任何幫助將不勝感激。

+3

你可以反序列化'json'到強類型的'C#'對象,然後修改你想要的條目。我認爲這會更容易。 –

+0

檢查此[鏈接](http://www.newtonsoft.com/json/help/html/modifyjson.htm) –

回答

1

事情是這樣的 -

var json = "[{'username':'John','currency':8,'pulls':[{'character':'person'},{'character':'loved one'}]},{'username':'Mike','currency':2,'pulls':[{'character':'noone'}]},{'username':'Clara','currency':5,'pulls':[{'character':'someone'}]}]"; 
var obj = JsonConvert.DeserializeObject<List<RootObject>>(json); 
var o = obj.FindIndex(a => a.username == "Mike"); 
obj[o].pulls.AddRange(new List<Pull>{ 
     new Pull{ 
      character = "Modified" 
     } 
    }); 

Console.WriteLine(JsonConvert.SerializeObject(obj)); 

public class Pull 
{ 
    public string character { get; set; } 
} 

public class RootObject 
{ 
    public string username { get; set; } 
    public int currency { get; set; } 
    public List<Pull> pulls { get; set; } 
} 

或者,你可能會感興趣的JSON Merge

一個可能的解決方案看起來像 -

var json = "[{'username':'John','currency':8,'pulls':[{'character':'person'},{'character':'loved one'}]},{'username':'Mike','currency':2,'pulls':[{'character':'noone'}]},{'username':'Clara','currency':5,'pulls':[{'character':'someone'}]}]"; 
var obj = JArray.Parse(json); 
var idx = obj.IndexOf(obj.FirstOrDefault(a => a["username"].ToString() == "Mike"));  
((JArray)obj[idx]["pulls"]).Add(JObject.Parse(@"{ 
     'character': 'new one' 
    }")); 
Console.WriteLine(obj[idx]); 
/*output - 
{ 
    "username": "Mike", 
    "currency": 2, 
    "pulls": [ 
    { 
     "character": "noone" 
    }, 
    { 
     "character": "new one" 
    } 
    ] 
} */ 
+0

謝謝!根據你的例子,我能找到一個解決方案,我將在我對這個問題的回答中寫出。 – BaqFish

0

經過多一點研究和你的幫助,我能夠首先將所有與Json的交互改變爲相同的代碼風格。

的新條目已經改變了這個:

public void CreateUser(string username) 
    { 
     try 
     { 
      string jsonUserString = File.ReadAllText(userPath); 
      var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString); 
      users.AddRange(new List<JsonCollection.User> { new JsonCollection.User { username = username, currency = 10, pulls = new List<JsonCollection.Character> { new JsonCollection.Character { character = "TemmieHYPE" } } } }); 
      string output = JsonConvert.SerializeObject(users, Formatting.Indented); 
      File.WriteAllText(userPath, output); 
     } 
     catch 
     { 
      Console.WriteLine("Error on CreateUser"); 
     } 
    } 

更新已更改爲這樣:

public void UpdateUserStats(string username, decimal value, int selection) 
    { 
     try 
     { 
      string jsonUserString = File.ReadAllText(userPath); 
      var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString); 
      int user = users.FindIndex(a => (a.username == username)); 
      if (user != -1) 
      { 
       switch (selection) 
       { 
        case 1: 
         users[user].currency += value; 
         break; 
        case 2: 
         users[user].secondsOnline += value; 
         break; 
        default: 
         break; 
       } 

       string output = JsonConvert.SerializeObject(users, Formatting.Indented); 
       File.WriteAllText(userPath, output); 

       //AddPullToUser(username, DateTime.Now.ToString()); //remove on live 
      } 
      else 
      { 
       CreateUser(username); 
      } 
     } 
     catch 
     { 
      Console.WriteLine("Error on UpdateCurrency"); 
     } 
    } 

最重要的是添加拉命令添加一個嵌套元素將JSON現在下面工作代碼:

public void AddPullToUser(string username, string pulledCharacter) 
    { 
     string jsonUserString = File.ReadAllText(userPath); 
     var users = JsonConvert.DeserializeObject<List<JsonCollection.User>>(jsonUserString); 
     int alreadyPulled = users.FindIndex(a => (a.username == username) && (a.pulls.FindIndex(b => b.character == pulledCharacter) > 0)); 
     if (alreadyPulled == -1) 
     { 
      int user = users.FindIndex(a => (a.username == username)); 
      users[user].pulls.AddRange(new List<JsonCollection.Character> { new JsonCollection.Character { character = pulledCharacter } }); 
      string output = JsonConvert.SerializeObject(users, Formatting.Indented); 
      File.WriteAllText(userPath, output); 
     } 
    } 

隨着「if(alreadypulled == -1)」的添加重複拉d不會被添加到Json文件中。