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>

输出获取到的文件内容:

posted @ 2024-10-18 11:32  请明月  阅读(10)  评论(0编辑  收藏  举报