2016-03-04 61 views
2

我有一個人工編輯的JSON(一個配置文件),需要以編程方式更改值,但保留註釋並可選擇保留格式。 Json.NET可能嗎?我有:Json.NET更改值並保留評論

JToken jobject = JToken.Parse(json); 
jobject["name"] = name; 
json = jobject.ToString(); 

但它會刪除所有的意見並重新格式化JSON字符串。

+0

我不認爲這是可行的,佈局信息(例如填充,無用空間)在反序列化中丟失。我想知道爲什麼這個文件可以手動修改和編程。 –

+0

@DannyChen格式化並不重要。不需要完全反序列化,例如[JsonTextReader](http://www.newtonsoft.com/json/help/html/readjsonwithjsontextreader.htm)保留評論。 – xmedeko

回答

2

保持評論是可能的,但格式是一個不同的故事,我不知道用Json.Net做這件事的正確方法,但JsonTextReaderLineNumberLinePosition,它應該可以使用它們來保存格式到一個程度,但它感覺hacky和脆弱,因此,如果它不是很重要,我建議使用Json.Net內部格式。

以下是更新屬性和保留註釋但不格式化的示例。

 private static string Update(string json, object update) 
     { 
      var updateObj = JObject.Parse(JsonConvert.SerializeObject(update)); 

      var result = new StringWriter(); 
      var writer = new JsonTextWriter(result); 
      writer.Formatting = Formatting.Indented; 

      var reader = new JsonTextReader(new StringReader(json)); 
      while (reader.Read()) 
      { 

       if (reader.Value == null) 
       { 
        writer.WriteToken(reader.TokenType); 
        continue; 
       } 

       var token= 
        reader.TokenType == JsonToken.Comment || 
        reader.TokenType == JsonToken.PropertyName || 
        string.IsNullOrEmpty(reader.Path) 
        ? null 
        : updateObj.SelectToken(reader.Path); 

       if (token == null) 
        writer.WriteToken(reader.TokenType, reader.Value); 
       else 
        writer.WriteToken(reader.TokenType, token.ToObject(reader.ValueType)); 
      } 

      return result.ToString(); 
     } 

     static void Main(string[] args) 
     { 
      string json = @"{ 
    //broken 
    'CPU': 'Intel', 
    'PSU': '500W', 
    'Drives': [ 
    'DVD read/writer' 
    /*broken*/, 
    '500 gigabyte hard drive', 
    '200 gigabype hard drive' 
    ] 
}"; 

      var update=Update(json, new { CPU = "AMD", Drives = new[] { "120 gigabytes ssd" } }); 
     }