数据读取与存储之Xml的简单存取类

XML

扩展标记语言 (Extensible Markup Language, XML)
用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进 行定义的源语言。
XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。
XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML
提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

优点:格式统一,符合标准;.容易与其他系统进行远程交互,数据共享比较方便。
缺点:XML文件庞大,文件格式复杂,传输占带宽;服务器端和客户端解析XML花费较多的资源和时间;需要花费大量代码来解析XML;

xml格式

<Root>
  <Class>
    <Teacher>
      <name>teacher0</name>
      <age>20</age>
    </Teacher>
    <Teacher>
      <name>teacher1</name>
      <age>20</age>
    </Teacher>
    <Student>
      <name>student0</name>
      <age>2</age>
    </Student>
    <Student>
      <name>student1</name>
      <age>4</age>
    </Student>
  </Class>
</Root>

c#写xml,并存储到对应文件

   using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System;
using System.IO;

public class XMLTools
{
    /// <summary>
    /// c#写xml
    /// </summary>
    /// <param name="path">存储xmll的文件路径</param>
    public static void WriteXML(string path)
    {
        XmlDocument doc = new XmlDocument();//声明文档对象
        XmlElement Root = doc.CreateElement("Root");
        XmlElement xel = doc.CreateElement("Class");
        //第一种写法
        XmlElement t1 = doc.CreateElement("Teacher");
        XmlElement t1name = doc.CreateElement("name");
        t1name.InnerXml = "teacher1";//赋值-
        XmlElement t1age = doc.CreateElement("age");
        t1age.InnerXml = "20";
        t1.AppendChild(t1name);
        t1.AppendChild(t1age);
        xel.AppendChild(t1);
        //第二种写法
        XmlElement t2 = doc.CreateElement("Teacher");
        t2.SetAttribute("name", "teacher2");
        t2.SetAttribute("age", "22");
        xel.AppendChild(t2);
        XmlElement s1 = doc.CreateElement("Student");
        //第一种写法
        XmlElement s1name = doc.CreateElement("name");
        s1name.InnerXml = "student1";//赋值-
        XmlElement s1age = doc.CreateElement("age");
        s1age.InnerXml = "10";
        s1.AppendChild(s1name);
        s1.AppendChild(s1age);
        xel.AppendChild(s1);
        //第二种写法
        XmlElement s2 = doc.CreateElement("Student");
        s2.SetAttribute("name", "student2");//给Student
        s2.SetAttribute("age", "12");
        xel.AppendChild(s2);

        Root.AppendChild(xel);//将xel加到Root下层
        doc.AppendChild(Root);
        doc.Save(path);
    } 
}

生成格式:

<Root>
  <Class>
    <Teacher>
      <name>teacher1</name>
      <age>20</age>
    </Teacher>
    <Teacher name="teacher2" age="22" />
    <Student>
      <name>student1</name>
      <age>10</age>
    </Student>
    <Student name="student2" age="12" />
  </Class>
</Root>

c#读取xml文件(针对于上面生成的xml文档)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System;
using System.Reflection;
using System.IO;

public class XMLTools
{
    /// <summary>
    /// 读取xml文档
    /// </summary>
    /// <param name="path">存储xml文档的路径</param>
    public static void ReadXml(string path)
    {
        XmlDocument doc = new XmlDocument();
        string filepath = path;
        doc.Load(filepath);//duqu 填充XML文档对象
        #region 1.由节点选择
        XmlNode root = doc.SelectSingleNode("Root");
        XmlNode cls = root.FirstChild;
        XmlNodeList teacherList = cls.SelectNodes("Teacher");
        foreach (var node in teacherList)
        {
            XmlElement xe = (XmlElement)node;
            if (xe.ChildNodes.Count>0)
            {
                XmlNode node1 = xe.SelectSingleNode("name");
                XmlNode node2 = xe.SelectSingleNode("age");
                Debug.Log(node1.InnerText);
                Debug.Log(node2.InnerText);

            }
            else
            {
                Debug.Log(xe.GetAttribute("name"));
                Debug.Log(xe.GetAttribute("age"));
            }
          
        }
        XmlNodeList studentList = cls.SelectNodes("Student");
        foreach (var node in teacherList)
        {
            XmlElement xe = (XmlElement)node;
            if (xe.ChildNodes.Count > 0)
            {
                XmlNode node1 = xe.SelectSingleNode("name");
                XmlNode node2 = xe.SelectSingleNode("age");
                Debug.Log(node1.InnerText);
                Debug.Log(node2.InnerText);

            }
            else
            {
                Debug.Log(xe.GetAttribute("name"));
                Debug.Log(xe.GetAttribute("age"));
            }

              
        }
        #endregion
        #region 2.由根节点选择
        //XmlNodeList teacherList1 = doc.SelectNodes("Root/Class/Teacher");
        //foreach (var item in teacherList1)
        //{
        //    XmlElement xe = (XmlElement)item;
        //    if (xe.ChildNodes.Count > 0)
        //    {
        //        XmlNode node1 = xe.SelectSingleNode("name");
        //        XmlNode node2 = xe.SelectSingleNode("age");
        //        Debug.Log(node1.InnerText);
        //        Debug.Log(node2.InnerText);

        //    }
        //    else
        //        Debug.Log(xe.GetAttribute("name") + "   " + xe.GetAttribute("age"));
        //}
        //XmlNodeList studentList1 = doc.SelectNodes("Root/Class/Student");
        //foreach (var item in studentList1)
        //{
        //    XmlElement xe = (XmlElement)item;
        //    if (xe.ChildNodes.Count > 0)
        //    {
        //        XmlNode node1 = xe.SelectSingleNode("name");
        //        XmlNode node2 = xe.SelectSingleNode("age");
        //        Debug.Log(node1.InnerText);
        //        Debug.Log(node2.InnerText);

        //    }
        //    else
        //        Debug.Log(xe.GetAttribute("name") + "   " + xe.GetAttribute("age"));
        //}
        #endregion
    }
}

一个xml存取工具类 (泛型)
功能包括:
1.将字典中的对象信息转化成Xml格式的字符串(通过反射)保存到对应的xml文档(泛型)
2.Xml文件转成对象信息存储到字典(泛型)

 using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System;
using System.Reflection;
using System.IO;

public class XMLTools
{
    /// <summary>
    /// 将字典中的对象信息转化成Xml格式的字符串(通过反射)保存到对应的xml文档
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="Dic"></param>
    /// <param name="path"></param>
    public static void ToXML<T>(Dictionary<int, T> Dic,string path)
    {
        XmlDocument doc = new XmlDocument();
        XmlElement root = doc.CreateElement("Root");
        foreach (var item in Dic)
        {
            Type t = typeof(T);//获得泛型类类型
            string Tname = t.Name;//获得泛型类名字
            XmlElement xe = doc.CreateElement(Tname);
            FieldInfo[] fis = t.GetFields();//获取泛型类的字段数组
            foreach (var fi in fis)
            {
                xe.SetAttribute(fi.Name, fi.GetValue(item.Value).ToString());//获取单个字段名字,值加入标签里
            }
            root.AppendChild(xe);
        }
        doc.AppendChild(root);
        doc.Save(path);
    }

    /// <summary>
    /// Xml文件转成对象信息
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path"></param>
    /// <returns></returns>
    public static Dictionary<int, T> ToObject<T>(string path) where T : new()
    {
        Dictionary<int, T> Dic = new Dictionary<int, T>();
        Type type = typeof(T);
        XmlDocument doc = new XmlDocument();
        string xmlstr= File.ReadAllText(path);
        doc.LoadXml(xmlstr);
        XmlNodeList nodeList = doc.SelectNodes("Root/" + type.Name);
        foreach (var item in nodeList)
        {
            XmlElement xe = (XmlElement)item;
            T tt = new T();
            FieldInfo[] fis = type.GetFields();
            foreach (var fi in fis)
            {
                string value = xe.GetAttribute(fi.Name);//得到类对应字段的值
                if (fi.FieldType.IsEnum)
                {
                    fi.SetValue(tt, Enum.Parse(fi.FieldType, value));
                }
                else
                {
                    if (fi.FieldType == typeof(int))
                    {
                        fi.SetValue(tt, int.Parse(value));
                    }
                    else if (fi.FieldType == typeof(float))
                    {
                        fi.SetValue(tt, float.Parse(value));
                    }
                    else
                    {
                        fi.SetValue(tt, value);
                    }
                }
            }
            int id = int.Parse( xe.GetAttribute("id"))//按照对象的id存储到字典(所以存储的对象要有id的属性)
            Dic.Add(id, tt);
        }
        return Dic;
    }
}

测试类:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
#if UNITY_EDITOR
      
        if (Input.GetKeyDown(KeyCode.X))
        {
            Debug.Log("x");
            // XMLTools.WriteXML(Application.dataPath + "/Resources/bb.xml");
            // XMLTools.ReadXml(Application.dataPath + "/Resources/bb.xml");

            Dictionary<int, AA> dic = new Dictionary<int, AA>();
            for (int i = 1; i < 4; i++)
            {
                AA aa = new AA();
                aa.id = i;
                aa.age = i*2;
                aa.name = "aaa"+i.ToString();
                dic.Add(aa.id, aa);
            }
            XMLTools.ToXML<AA>(dic, Application.dataPath + "/Resources/bb.xml");
            Dictionary<int, AA> a = XMLTools.ToObject<AA>(Application.dataPath + "/Resources/bb.xml");
            foreach (var item in a)
            {
                Debug.Log(item.Key+"  "+ item.Value.name + "  " + item.Value.age);
            }
        }
#endif
    }
}

[Serializable]
public class AA
{
    public int id ;
    public string name = "";
    public int age = 0;

}

生成xml

<Root>
  <AA id="1" name="aaa1" age="2" />
  <AA id="2" name="aaa2" age="4" />
  <AA id="3" name="aaa3" age="6" />
</Root>

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值