XML
概念
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>
输出获取到的文件内容: