概念
C# 中讀取Xml檔案有兩種方式
注意這裡沒有展示包含屬性的讀取,如果包含屬性DataSet方法的讀取會相對複雜一些
讀取檔案
1.使用DataSet讀取對應檔案
public DataSet GetXmlDataset(string path)
{
DataSet dataSet = new DataSet();
dataSet.ReadXml(path);//ReadXml(String)使用指定的檔案將 XML架構和資料讀入 DataSet。
return dataSet;
}
2.使用XmlDocument讀取對應檔案需要引入using System.Xml模組
public XmlNode GetXmlXmlDocument(string path)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(path);
XmlNode node = xmlDocument.DocumentElement;
return node;
}
如果是簡單的讀取可以直接使用DataSet讀取檔案,XmlDocument可以操作更復雜的檔案。
寫入檔案
使用XmlDocument中的CreateElement這個Api建立節點,操作完成後直接使用Save(Path)進行儲存。
下面這段程式碼實現了向xml檔案中寫入一個節點,然後儲存
public void WriteDocument(XmlDocument xmlDocument, string path)
{
XmlElement xn = xmlDocument.CreateElement("student");
XmlElement xesub1 = xmlDocument.CreateElement("name");
xesub1.InnerText = "趙九";//設定文字節點
xn.AppendChild(xesub1);//新增到<xn>節點中
XmlElement xesub2 = xmlDocument.CreateElement("sex");
xesub2.InnerText = "男";//設定文字節點
xn.AppendChild(xesub2);//新增到<xn>節點中
XmlElement xesub3 = xmlDocument.CreateElement("old");
xesub3.InnerText = "50";//設定文字節點
xn.AppendChild(xesub3);//新增到<xn>節點中
xmlDocument.SelectSingleNode("studentList").AppendChild(xn);
xmlDocument.Save(path);
}
程式碼示例
這段程式碼示例,主要作用是將xml檔案中表示對應含義的節點轉換為對應的類,這裡使用了以上兩種方法讀取檔案,使用XmlDocument寫入檔案。
使用DataSet讀取並進行轉換
這裡的轉換我使用了泛型擴充套件這個方法,具體實現思路:
1.獲取所有列標籤並且儲存在列表中
2.讀取每一行資料並且使用反射生成物件
3.根據讀取出的資料使用提前儲存好的FieldInfo進行約束和賦值物件
4.將物件新增入列表中
/// <summary>
/// 讀取不帶標籤的XMl, 並且將資料使用反射建立對應的類,最後返回所有的物件
/// </summary>
/// <typeparam name="T">需要將該檔案中的節點轉換的類</typeparam>
/// <param name="list">儲存轉換的類</param>
/// <param name="path">檔案地址</param>
public void GetXmlData<T>(ref List<T> list, string path) where T : new()
{
DataSet dataSet = GetXmlDataset(path);
List<FieldInfo> fieldinfos = new List<FieldInfo>();
List<string> columns = new List<string>();
Type type = typeof(T);
foreach (object item in dataSet.Tables[0].Columns)
{
FieldInfo fieldInfo = type.GetField(item.ToString());
if (fieldInfo != null)
{
fieldinfos.Add(fieldInfo);
}
columns.Add(item.ToString());
}
for (int i = 0; i < dataSet.Tables[0].Rows.Count; i++)
{
T obj = (T)Activator.CreateInstance(type);
for (int j = 0; j < columns.Count; j++)
{
FieldInfo info = type.GetField(columns[j].ToString());
if (info != null)
{
info.SetValue(obj, Convert.ChangeType(dataSet.Tables[0].Rows[i][columns[j]], info.FieldType));
}
}
list.Add(obj);
}
}
使用XmlDocument讀取並進行轉換
使用XmlDocument稍微有一些區別但具體流程還是和上面一樣
public void GetDocumentData<T>(ref List<T> list, string path) where T : new()
{
XmlNode node = GetXmlXmlDocument(path);
List<FieldInfo> fieldinfos = new List<FieldInfo>();
List<string> columns = new List<string>();
Type type = typeof(T);
foreach (XmlNode item in node.SelectNodes(type.ToString())[0].ChildNodes)
{
FieldInfo fieldInfo = type.GetField(item.Name);
if (fieldInfo != null)
{
fieldinfos.Add(fieldInfo);
}
columns.Add(item.Name);
}
for (int i = 0; i < node.SelectNodes(type.ToString()).Count; i++)
{
T obj = (T)Activator.CreateInstance(type);
for (int j = 0; j < columns.Count; j++)
{
FieldInfo info = type.GetField(columns[j].ToString());
if (info != null)
{
info.SetValue(obj, Convert.ChangeType(node.SelectNodes(type.ToString())[i].ChildNodes[j].InnerText, info.FieldType));
}
//Debug.Log(node.SelectNodes(type.ToString())[i].ChildNodes[j].Attributes["id"].InnerText);
}
list.Add(obj);
}
}
以下是該指令碼的全部程式碼,貼一下
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Xml;
using UnityEngine;
public class XMLLoad : MonoBehaviour
{
public void Start()
{
string path = Application.dataPath+ "/Resources/Xml/XMLFile1.xml";
List<student> students = new List<student>();
GetDocumentData<student>(ref students, path);
DisPlayList(students);
GetXmlData<student>(ref students, path);
DisPlayList(students);
}
public void DisPlayList(List<student> students)
{
foreach (student student in students)
{
Debug.Log(student.ToString());
}
}
/// <summary>
/// 讀取不帶標籤的XMl, 並且將資料使用反射建立對應的類,最後返回所有的物件
/// </summary>
/// <typeparam name="T">需要將該檔案中的節點轉換的類</typeparam>
/// <param name="list">儲存轉換的類</param>
/// <param name="path">檔案地址</param>
public void GetXmlData<T>(ref List<T> list, string path) where T : new()
{
DataSet dataSet = GetXmlDataset(path);
List<FieldInfo> fieldinfos = new List<FieldInfo>();
List<string> columns = new List<string>();
Type type = typeof(T);
foreach (object item in dataSet.Tables[0].Columns)
{
FieldInfo fieldInfo = type.GetField(item.ToString());
if (fieldInfo != null)
{
fieldinfos.Add(fieldInfo);
}
columns.Add(item.ToString());
}
for (int i = 0; i < dataSet.Tables[0].Rows.Count; i++)
{
T obj = (T)Activator.CreateInstance(type);
for (int j = 0; j < columns.Count; j++)
{
FieldInfo info = type.GetField(columns[j].ToString());
if (info != null)
{
info.SetValue(obj, Convert.ChangeType(dataSet.Tables[0].Rows[i][columns[j]], info.FieldType));
}
}
list.Add(obj);
}
}
public void GetDocumentData<T>(ref List<T> list, string path) where T : new()
{
XmlNode node = GetXmlXmlDocument(path);
List<FieldInfo> fieldinfos = new List<FieldInfo>();
List<string> columns = new List<string>();
Type type = typeof(T);
foreach (XmlNode item in node.SelectNodes(type.ToString())[0].ChildNodes)
{
FieldInfo fieldInfo = type.GetField(item.Name);
if (fieldInfo != null)
{
fieldinfos.Add(fieldInfo);
}
columns.Add(item.Name);
}
for (int i = 0; i < node.SelectNodes(type.ToString()).Count; i++)
{
T obj = (T)Activator.CreateInstance(type);
for (int j = 0; j < columns.Count; j++)
{
FieldInfo info = type.GetField(columns[j].ToString());
if (info != null)
{
info.SetValue(obj, Convert.ChangeType(node.SelectNodes(type.ToString())[i].ChildNodes[j].InnerText, info.FieldType));
}
//Debug.Log(node.SelectNodes(type.ToString())[i].ChildNodes[j].Attributes["id"].InnerText);
}
list.Add(obj);
}
}
public DataSet GetXmlDataset(string path)
{
DataSet dataSet = new DataSet();
dataSet.ReadXml(path);
return dataSet;
}
public XmlNode GetXmlXmlDocument(string path)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(path);
XmlNode node = xmlDocument.DocumentElement;
//WriteDocument(xmlDocument, path);
return node;
}
public void WriteDocument(XmlDocument xmlDocument, string path)
{
XmlElement xn = xmlDocument.CreateElement("student");
XmlElement xesub1 = xmlDocument.CreateElement("name");
xesub1.InnerText = "趙九";//設定文字節點
xn.AppendChild(xesub1);//新增到<xn>節點中
XmlElement xesub2 = xmlDocument.CreateElement("sex");
xesub2.InnerText = "男";//設定文字節點
xn.AppendChild(xesub2);//新增到<xn>節點中
XmlElement xesub3 = xmlDocument.CreateElement("old");
xesub3.InnerText = "50";//設定文字節點
xn.AppendChild(xesub3);//新增到<xn>節點中
xmlDocument.SelectSingleNode("studentList").AppendChild(xn);
xmlDocument.Save(path);
}
}
public class student
{
public int id;
public string name;
public string sex;
public int old;
public override string ToString()
{
return $"id:{this.id},name:{this.name},sex:{this.sex},old:{this.old}";
}
}
表現
XMLFile1.xml 檔案內容
<?xml version="1.0" encoding="utf-8"?>
<studentList>
<student>
<name>張三</name>
<sex>男</sex>
<old>20</old>
</student>
<student>
<name>李四</name>
<sex>女</sex>
<old>21</old>
</student>
<student>
<name>王五</name>
<sex>男</sex>
<old>40</old>
</student>
<student>
<name>王五</name>
<sex>女</sex>
<old>18</old>
</student>
<student>
<name>鄭七</name>
<sex>女</sex>
<old>31</old>
</student>
<student>
<name>趙九</name>
<sex>男</sex>
<old>50</old>
</student>
</studentList>
輸出獲取到的檔案內容: