1. 程式人生 > 實用技巧 >使用Newtonsoft.Json進行Json與XML相互轉換

使用Newtonsoft.Json進行Json與XML相互轉換

XML的解析得考慮子節點父節點,讓人頭昏眼花,而JSON的解析好像沒啥難度。今天突然發現Newtonsoft.Json中有關於Json和XML互轉的方法,所以順帶記錄總結一下。

一、關於Newtonsoft.Json

Newtonsoft.Json(Json.Net)是一款.NET中開源的Json序列化和反序列化類庫。

Json.Net是一個讀寫Json效率比較高的.Net框架,.Json.Net 使得在.Net環境下使用Json更加簡單。通過Linq To JSON可以快速的讀寫Json,通過JsonSerializer可以序列化你的.Net物件。讓你輕鬆實現.Net中所有型別(物件,基本資料型別等)和Json的轉換。

二、Json與類物件之間相互轉換

物件序列化Json字串:

JsonConvert.SerializeObject(object value)

Json字串反序列化為物件:

JsonConvert.DeserializeObject(string value)
JsonConvert.DeserializeObject<T>(string value)

使用例子:

TaskData資料類:

    public class TaskData
    {
        public int ID;//任務ID
        public string Name;//任務名稱
        public string Des;//任務描述
        public int MaxNum;//最大人數
    }

序列化和反序列化呼叫:

	void Start () {
		TaskData data = new TaskData();
		data.ID = 0;
		data.Name = "排戰術 進攻戰鬥";
		data.Des = "開進展開、協同攻擊、奪取陣地。";
		data.MaxNum = 4;

        string json = JsonConvert.SerializeObject(data);
        Debug.Log(json);//Unity中列印日誌輸出
        TaskData data= JsonConvert.DeserializeObject<TaskData>(json);
	}

非常簡單,但需要注意一點,如果你的物件類中涉及繼承、特定屬性存在NULL值之類比較複雜的操作,需要使用序列化和反序列化帶有JsonSerializerSettings引數的過載。

這些操作可以參考官方文件,總之如果你的Json反序列化失敗,Json序列化異常,很可能是需要設定JsonSerializerSettings。
官方文件說明:https://www.newtonsoft.com/json/help/html/SerializationSettings.htm
也可以參考另一篇部落格,但不如官方文件那麼全:
https://www.cnblogs.com/zhaoshujie/p/11077843.html

三、Json與XML相互轉換

XML序列化為Json字串:

JsonConvert.SerializeXmlNode(XmlNode node)

Json反序列化為XML物件:

JsonConvert.DeserializeXmlNode(string value)

我在這裡用一個稍微複雜的例子,涉及資料類包含List:

使用例子:

TaskData資料類:

    public class TaskData
    {
        public int ID;//任務ID
        public string Name;//任務名稱
        public string Des;//任務描述
        public int MaxNum;//最大人數
    }

任務配置類:

	public class TaskConfigData
	{
    	public List<TaskData> TaskDataList = new List<TaskData>();
	}

Json反序列化為XML,並儲存本地:

void Save() {
	string XMLpath = Application.streamingAssetsPath + "/TaskConfig.xml";//XMLpath 為XML文件儲存路徑
	//準備序列化資料
	TaskConfigData	_taskConfigData = new TaskConfigData();
	TaskData data = new TaskData();
	data.ID = 0;
	data.Name = "排戰術 進攻戰鬥";
	data.Des = "開進展開、協同攻擊、奪取陣地。";
	data.MaxNum = 4;
	_taskConfigData.TaskDataList.Add(data);
	
	//資料序列化為Json字串
	string json = JsonConvert.SerializeObject(_taskConfigData);
	
	//Json反序列化為Xml
	XmlDocument xml = JsonConvert.DeserializeXmlNode(json, "", true);
    xml.Save(XMLpath);//儲存,

}

讀取XML序列化為Json

void Read() {
	//讀取本地Xml
	string xmlStr = System.IO.File.ReadAllText(Application.streamingAssetsPath + "/TaskConfig.xml");
	XmlDocument doc = new XmlDocument();
	doc.LoadXml(xmlStr);
	
	//XML序列化為Json
	string json = Newtonsoft.Json.JsonConvert.SerializeXmlNode(doc,Formatting.None,false);

	//Json序列化為資料
	TaskConfigData _taskConfigData = JsonConvert.DeserializeObject<TaskConfigData>(json);
	Debug.Log(_taskConfigData.TaskDataList.Count);//Unity列印日誌輸出
}
                        

如果你在XML和Json相互轉換陣列或集合出現問題,像這種錯誤:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'EasyNote.Translate.Bing.Rootobject' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object

就需要注意一下,我用的是DeserializeXmlNode()和SerializeXmlNode()方法的過載。為什麼用過載呢?因為我的資料類中包含List泛型資料,若直接轉換會報錯。


DeserializeXmlNode過載中,引數deserializeRootElementName指的是建立XML文件的根節點名,傳入""不建立根節點,writeArrayAttribute是否用到陣列屬性,我這裡用到了List所以必須設定為true。

生成的XML:

可以看到XML添加了陣列屬性。

SerializeXmlNode過載中,引數formatting指的是Json字串格式有沒有縮排,我也用的預設值None。omitRootObject獲取或設定一個值,該值指示是否寫入根JSON物件,我之前設定""沒有寫入,所以設定false。

四、總結

Newtonsoft.Json確實相當強大,目前還只是用了小小的一部分功能,以後會再看看原始碼,學習更高階使用方法。
附帶原始碼地址:
https://github.com/JamesNK/Newtonsoft.Json
官網地址:
https://www.newtonsoft.com/json
官方文件地址:
https://www.newtonsoft.com/json/help/html/Introduction.htm