xml在unity中,经常用来保存本地数据,我们在处理xml文件的时候,通常是先创建一个xml对应的数据类,然后将xml解析的每一个element封装成对象,在保存的list或者diction集合中。解析xml的过程大部分都是相同的,但是不同的数据类,对应的字段,相差较大,所以之前在解析的时候,都是单独解析的。
最近闲来无事,就讲xml解析的方法进行了加工,利用c#的反射技术和泛型的特点,创建一个xml解析工具,这样,我们只用传递xml文件以及生产文件的数据类,就可以轻松搞定繁琐的xml转换了。
首先我们需要一个xml文件,手写xml文件太费劲了,我们可以先在Excel中创建数据,保存为CSV格式的文件,然后在写个工具,把csv文件转换为xml文件(虽然这样也有点麻烦,但是感觉比直接写xml要好一点)

直接上代码


using UnityEngine;
using System.Xml;
using System.IO;
using UnityEditor;
//using System;/// <summary>
/// 把给定列数的csv文件转换为xml文件.该类文件放在file/csv文件夹下
/// csv文件的格式:第一行为属性的名称,后面若干行为属性的值
/// 生成的xml文件,放在StreamingAssets/xml目录下
/// </summary>
public class CsvToXmlTools : Editor {[MenuItem("Assets/CsvToXml/Story")]static void CsvToXml_Story(){string path=AssetDatabase.GetAssetPath (Selection.activeObject);if(path.EndsWith(".csv"))loadFile (path);}/// <summary>/// 加载csv文件,并按行读取数据./// </summary>/// <param name="filePath">文件路径.</param>/// <param name="columCount">列数.</param>static  void loadFile(string filePath){string path = filePath;string saveName = Path.GetFileNameWithoutExtension(path);string xmlPath = Application.streamingAssetsPath + "/xml/" +saveName+ ".xml";CreatXmlFile (xmlPath);//创建或者覆盖之前的xml文件//读取csv文件FileStream fs = new FileStream (path,FileMode.Open);using(StreamReader sr=new StreamReader(fs)){string str = sr.ReadLine ();string[] keys = str.Split (',');//保存属性名称
//          str = sr.ReadLine ();
//          addToXml (new string[]{"dataType"},new string[]{str},xmlPath);//保存数据格式int columCount = keys.Length ;while ((str=sr.ReadLine ())!=null) {string[] arr = str.Split (',');if (keys.Length ==  arr.Length) {addToXml (keys,arr,xmlPath);//保存读取的数据到xml文件中} elseDebug.LogError ("data error"+str);}}fs.Close ();Debug.Log ("转换文件结束");}/// <summary>/// 为xml文件添加新的节点./// </summary>/// <param name="keys">需要添加的数据的健.</param>/// <param name="arr">需要添加的数据值.</param>/// <param name="xmlPath">xml文件的位置.</param>static  void addToXml(string[] keys,string[] values,string xmlPath){XmlDocument xmldoc = new XmlDocument ();xmldoc.Load (xmlPath);XmlNode root= xmldoc.SelectSingleNode ("root");XmlElement record = xmldoc.CreateElement ("Record");for (int i = 0; i < keys.Length; i++) {
//          Debug.Log(keys[i]+"-------"+values[i]);record.SetAttribute (keys [i], values [i]);}root.AppendChild (record);xmldoc.Save (xmlPath);}/// <summary>/// 创建一个新的xml文件./// </summary>/// <param name="path">xml文件的保存路径.</param>static  void CreatXmlFile(string path){XmlDocument doc = new XmlDocument ();XmlDeclaration dec= doc.CreateXmlDeclaration("1.0", "utf-8", null);doc.AppendChild (dec);XmlNode root= doc.CreateElement ("root");doc.AppendChild (root);doc.Save (path);Debug.Log ("save path=" + path);}
}

这是我们的编辑器工具,选择我们的csv文件,,右键,选CsvToXml/Story,即可,生成的xml文件自动保存在StreamingAssets/xml/ 目录下,没有该目录的需要自己手动创建一下,代码里就懒得做处理了,��

然后就是我们的xml解析类,我们把xml解析放在基类里面,子类只用继承调用即可
每一个xml文件,会有一个单独的数据类和它对应,每一个字段对应一个属性

首先是我们的xml文件

<?xml version="1.0" encoding="utf-8"?>
<root><Record id="1" chapter="1" index="1" content="你是故意与我争斗,以骗取启魂邪教的信任?" hero="aa" heroName="洛昭言" type="true" /><Record id="2" chapter="1" index="2" content="没错。不瞒兄弟,我们两人昨天刚到盈辉堡,这丫头就上了刚才那家伙的当,把钱全给了那个什么圣宗。没办法,我只好装傻跟那个教使套近乎,看能不能想法把钱弄回来" hero="bb" heroName="越今朝" type="false" /><Record id="3" chapter="1" index="3" content="我没上当,以前就见过穿这种衣服的骗子啊。可是你说过,要是别人都去做一件事,我最好也跟着做。昨天好多人都把钱给他了啊。" hero="aa" heroName="祈" type="true" /><Record id="4" chapter="1" index="4" content="我教过你明知是坑还往里跳吗?" hero="aa" heroName="越今朝" type="true" /><Record id="5" chapter="1" index="5" content="我教过你明知是坑还往里跳吗?" hero="bb" heroName="祈" type="false" /><Record id="6" chapter="2" index="1" content="我一定是上辈子欠你的…… " hero="aa" heroName="越今朝" type="true" /><Record id="7" chapter="2" index="2" content="加斯递交的年代" hero="bb" heroName="洛昭言" type="false" /><Record id="8" chapter="2" index="3" content=":那个……两位……" hero="aa" heroName="aa" type="true" /><Record id="9" chapter="2" index="4" content="呃……咳咳。我叫越今朝,这是越祈,兄弟怎么称呼?" hero="bb" heroName="越今朝" type="false" /><Record id="10" chapter="2" index="5" content="洛昭言" hero="aa" heroName="洛昭言" type="true" /><Record id="11" chapter="2" index="6" content="难道您就是这一带有名的昙华洛家的家主?" hero="bb" heroName="越今朝" type="false" />
</root>

然后使我们的数据基类

public class ModelBase  {public int id;
}

数据类

public  class StoryEntry:ModelBase{public string chapter;public string index;public string content;public string hero;public string heroName;public bool type;//      public void show(){//          string str = "";
//          //取得当前方法命名空间
//          str += "命名空间名:" + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace + "\n";
//          //取得当前方法类全名
//          str += "类名:" + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName + "\n";
//          Debug.Log (str);
//      }}

xml解析的基类

using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Reflection;public class ModelMgrBase {public Dictionary<int,ModelBase> dataDic = new Dictionary<int, ModelBase>();public virtual void Init(){}/// <summary>/// 从 xml 中加载数据并保存到字典里面./// </summary>/// <param name="path">Path.</param>/// <param name="keys">Keys.</param>/// <param name="className">Class name.</param>protected void LoadFromXml(string path,string[] keys,string className,string[] dataTypes){XmlDocument xml = new XmlDocument ();xml.Load (path);XmlNode root= xml.SelectSingleNode ("root");XmlNodeList nodes = root.ChildNodes;//      string[] dataTypes=GetDataType ((XmlElement)nodes [0]);for (int i = 1; i < nodes.Count; i++) {XmlElement item = nodes[i] as XmlElement;Assembly assembly = Assembly.GetExecutingAssembly();//获取命名空间ModelBase model= (ModelBase)assembly.CreateInstance (className);//实例化对象if (model == null)continue;System.Type type= model.GetType ();for (int j = 0; j < keys.Length; j++) {FieldInfo fi= type.GetField (keys [j]);object dataValue=null;switch (dataTypes[j]) {case "int":dataValue = int.Parse (item.GetAttribute (keys [j]));break;case "float":dataValue = float.Parse (item.GetAttribute (keys [j]));break;case "bool":dataValue = bool.Parse (item.GetAttribute (keys [j]));break;case "string":dataValue =item.GetAttribute (keys [j]);break;default:break;}if(fi!=null){fi.SetValue(model,dataValue);}}dataDic.Add (model.id,model);}}//  string[] GetDataType(XmlElement element){////        Debug.Log (bool.Parse("true"));
////        Debug.Log (float.Parse("1.23"));
//      string dt = element.GetAttribute ("dataType");
//      return dt.Split(',');
//  }/// <summary>/// 通过ID从集合中查找数据./// </summary>/// <param name="id">Identifier.</param>/// <typeparam name="T">The 1st type parameter.</typeparam>public T GetDataById<T>(int id) where T:ModelBase{T model;ModelBase mb;dataDic.TryGetValue (id, out mb);if(dataDic.ContainsKey(id)){return (T)dataDic[id];}else return default(T);}/// <summary>/// 通过className创建实例对象./// </summary>/// <returns>The instance by class name.</returns>/// <param name="className">Class name.</param>/// <typeparam name="T">The 1st type parameter.</typeparam>private T CreateInstanceByClassName<T>(string className){Assembly assembly = Assembly.GetExecutingAssembly();object obj= assembly.CreateInstance (className);//      obj.GetType().GetField("chapter").SetValue(obj,21); //获取指定名称的字段//      System.Reflection.PropertyInfo propertyInfo = type.GetProperty("chapter"); //获取指定名称的属性//      propertyInfo.SetValue(obj,21,null);return (T)obj;}}

xml数据管理类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Reflection;public class StoryMgr:ModelMgrBase  {public  class StoryEntry:ModelBase{public string chapter;public string index;public string content;public string hero;public string heroName;public bool type;public void show(){string str = "";//取得当前方法命名空间str += "命名空间名:" + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace + "\n";//取得当前方法类全名str += "类名:" + System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName + "\n";Debug.Log (str);}}private static StoryMgr instance;public static StoryMgr Instance{get{ if (instance == null)instance = new StoryMgr ();return instance;}}/// <summary>/// 初始化数据,然后假装xml,保存到字典集合中./// </summary>public override void Init (){base.Init ();string path=Application.streamingAssetsPath+"/xml/story.xml";string[] keys = new string[]{ "id","chapter","index","content","hero","heroName","type"};// xml 的属性名称string[] dataTypes = new string[]{"int","string","string","string","string","string","bool" };//对应的数据类型string className = "StoryMgr+StoryEntry"; //classname=命名空间+“.”+类全名,如果命名空间为空,只用添加类全名LoadFromXml (path,keys,className,dataTypes);}}

最后,创建一个mono脚本,测试一下我们的方法

using UnityEngine;
using System.Collections;public class testScript : MonoBehaviour {// Use this for initializationvoid Start () {StoryMgr.Instance.Init ();StoryMgr.StoryEntry st=StoryMgr.Instance.GetDataById<StoryMgr.StoryEntry> (3);Debug.Log (st.id+"--"+st.content+"--"+st.type);}// Update is called once per framevoid Update () {}
}

以后再解析其他xml的时候,只要创建好数据类,然后xml管理类直接继承xml解析类,就可以将xml的数据保存到数据字典里面。

参考demo:http://download.csdn.net/detail/u011484013/9884278,unity5.4

unity xml反序列化为数据类相关推荐

  1. Python: Json串反序列化为自定义类对象

    最近刚接触到python,就想到了如何反序列化json串.网上找了一下,大部分都是用json模块反序列化为python数据结构(字典和列表).如果对json模块不了解的参考菜鸟教程.然后我在此基础上将 ...

  2. XML 反序列化为Model

    什么也不多说,直接贴代码 需要反序列的XML <?xml version='1.0' encoding='utf-8' ?> <GetCitiesListResponse>&l ...

  3. 利用VS2012自带功能,将xml文档反序列化为对象

    一.要注意的事项 1.项目框架在.NET Framework 4.5及其之上,才支持将xml反序列化为对象 2.序列化和反序列化名词解释 ①序列化是将对象状态转换为可保持或传输的格式的过程. ②反序列 ...

  4. Unity使用Newtonsoft.Json插件实现XML与JSON数据的互转

    文章目录 插件介绍 Unity中使用Newtonsoft.Json进行xml与json互转 搭建demo场景 编写脚本实现json与xml互转的方法 demo演示效果 demo源工程 关于Newton ...

  5. JavaScriptSerializer类 对象序列化为JSON,JSON反序列化为对象

    JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据.说白了就是能够直接将一个C#对象传送到前台页面成为javascript对 ...

  6. json序列化 java对象_Json 数据反序列化为Java对象

    前言:我们在项目中经常用到的是Json格式的数据,如果是将一个被Jackson转化为JSON数据格式的Java对象进行操作,我们就需要将JSON数据再反序列化为Java对象. 1.实体对象 packa ...

  7. 【Unity】解析Excel数据,并自动创建对应的C#类

    升级版传送门: [Unity]升级版·Excel数据解析,自动创建对应C#类,自动创建ScriptableObject生成类,自动序列化Asset文件_萧然CS的博客-CSDN博客Excel注释操作: ...

  8. 用友华表Cell控件数据 xml 构造器的操作类

    using System; using System.Collections; using System.Data; using System.Xml; /// <summary>     ...

  9. C#中XML、JSON、类T数据格式之间的转换

    在C#中,XML与JSON之间可以相互转化 XML与T类型也可以相互转化[XML有且只有一个根节点] JSON与T类型也可以相互转化. 新建控制台应用程序JsonToXmlToClassDemo,(. ...

  10. 使用JDK的JAXB将XML转化为JAVA对象,原生支持

    工作中有时候会对接XML的数据,其实JDK中的JAXB已经集成了相应的API,可以将XML转化为JAVA对象 使用起来只需关注几个注解,由于是原生支持,也不用引入第三方JAR包,总体来说还算方便. p ...

最新文章

  1. 英伟达的雄心:成为AI时代的计算平台
  2. com学习笔记(6)类厂
  3. PostgresSQL生成UUID
  4. 黄牛凭什么抢走我们的票?
  5. Kubernetes排错:用容器的元数据提供新思路
  6. Android官方开发文档Training系列课程中文版:分享简单数据之添加简单的分享行为
  7. 莫比乌斯函数之和(51nod 1244)
  8. 名词解释——元数据和数据字典
  9. 简约的手机APP自适应下载页HTML源码
  10. TeX Live 2021 从卸载到安装指南
  11. 人类如何学习和表征网络?
  12. 企业私有云资源规划及设计
  13. rocketdock 打不开 有进程
  14. Rails——migration
  15. 第12篇:给任意java程序挂Socks5代理方法
  16. C语言实现飞机售票系统
  17. sms 短信通平台 发送短信
  18. Metso定位器的参数及调试步骤
  19. LL(1)文法中FIRST集和FOLLOW集的计算方法
  20. 关于ceph的一些问题及解决

热门文章

  1. 自己动手画一个CPU——Logisim,下
  2. vue图片连拼实现gif图效果
  3. 该如何去认知Level 2 十档行情数据?
  4. 逆向分析学习入门教程
  5. esp8266连接阿里云 (课程设计 附源码)
  6. Windows Server安装 IIS 时报错:刷新服务器管理器时出现意外错 误:无法打开匿名级安全令牌。(异常来自 HRESULT:0x80070543)
  7. 视频录制——SurfaceView + MediaRecorder 实现视频录制功能
  8. 马三步内可以到达的点
  9. 重装系统后,硬盘分区丢失的解决办法
  10. 搞明白activated和deactivated