我有一個簡單的 JSON,我想重命名(可能通過復制然后洗掉)一個鍵。.NET 小提琴:
const string input = @"{ ""foo"": [{""a"": 1}, {""b"": null}] }";
var node = JsonNode.Parse(input);
Console.WriteLine(node); // Output: the JSON
Console.WriteLine(node["foo"][0]["a"]); // Output: 1
// How to copy/rename?
node["bar"] = node["foo"];
Console.WriteLine(node["bar"][0]["a"]); // Should be 1
{
"foo": [
{
"a": 1
},
{
"b": null
}
]
}
如何復制/重命名它?我嘗試使用node["foo"].AsValue(),但效果不佳。錯誤是
節點必須是“JsonValue”型別
我剛剛通過轉換為 JSON 字串并再次決議它找到了一種解決方法,但我希望有更好的方法來做到這一點。
node["bar"] = JsonNode.Parse(node["foo"].ToJsonString());
uj5u.com熱心網友回復:
所以你擁有的是一個 JSON 物件,所以JsonNode.Parse會真正回傳 a JsonObject,所以首先我們需要轉換它:
var jsonObject = JsonNode.Parse(input)!.AsObject(); // null check omitted for brevity
現在讓我們進行重命名。重命名實際上是洗掉具有舊屬性的物件,然后使用新名稱讀取它。所以:
var node = jsonObject["foo"]; // take a reference to foo so we don't lose it
jsonObject.Remove("foo"); // detach from parent
jsonObject.Add("bar", node); // attach with new name
您需要先洗掉它然后將其添加回來的原因是JsonNode物件具有父物件,并且如果物件或陣列已經有父物件,則不允許您將節點添加到物件或陣列中。因此,您首先需要使用 將其與其父級分離Remove,然后您可以使用 將其重新添加到新名稱下Add。
現在,這會修改原始 JSON 物件。如果你想保持原樣不變,你必須先克隆它。這是一個問題,因為沒有辦法克隆JsonNode. 你可以這樣做:
var clone = new JsonObject(jsonObject);
它會編譯,但是在運行時你會遇到一個例外,因為這只是將節點從一個物件添加到下一個物件,并且正如我們已經確定的那樣,你不能將已經有父物件的物件添加到另一個物件。您必須首先克隆每個子節點并添加它們。
據我所知,JsonNodes命名空間無法對 JSON 節點進行深度克隆。這似乎是一個疏忽。您可以通過遞回列舉檔案中的節點并創建它們來手動完成,或者只決議檔案兩次。
uj5u.com熱心網友回復:
您的問題更新將“欄”添加到現有節點物件。如果要創建一個新物件,它是現有節點物件的副本,可以通過 2 種主要方式
- 最簡單最有效的方法是更改??json字串
string newInput = input.Replace("\"foo\":","\"bar\":");
var newNode=JsonNode.Parse(newInput);
- 或者創建新的 json 物件
var newNode = new JsonObject( new[] { KeyValuePair.Create<string,JsonNode>("bar",
JsonNode.Parse(node["foo"].ToJsonString()) )});
結果
{
"bar": [
{
"a": 1
},
{
"b": null
}
]
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/426818.html
標籤:C# json 反序列化 .net-6.0 system.text.json
上一篇:遍歷JSON陣列并回傳元素的子集
下一篇:洗掉JSON陣列中的值
