C#之XML读取
一、XML读取一,只有一个父节点的情况下,只需要获取该父节点下所有的子节点,然后对每个节点进行相关的处理,根据Object--Model--Connection(对象模型关系映射处理)就能得到想要的数据,或者是数据对象。
<Item> <Item id="101" name="Admin01" age="23"/> <Item id="102" name="Admin02" age="24"/> <Item id="103" name="Admin03" age="25"/> <Item id="104" name="Admin04" age="26"/> </Item>
面对上述情况的XML文件时,读取代码如下:
/// <summary> /// 获取XMl父节点下所有的子节点(当所有的子节点全部在总父节点下时) /// </summary> /// <param name="path">xml文件所在的路径</param> /// <returns></returns> public XmlNodeList GetXmlNodes(string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); XmlNode node = doc.FirstChild; XmlNodeList xmlList = node.ChildNodes; return xmlList; }
当获取到所有的子节点后,将节点对应到模型类,然后将节点数据转换成对象,这是一个泛型的方法,可以通用,传入对应的节点,以及要获取的对象类型,就能获取到对应的对象列表,代码如下:
/// <summary> /// 模型映射到对象 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="nodeList"></param> /// <returns></returns> public List<T> GetDataByModel<T>(List<XmlNode> nodeList) { List<T> list = new List<T>(); Type t = typeof(T); MethodInfo func = t.GetMethod("Parse");//这里使用了C#反射的技术 int i = 0; while (i<nodeList.Count) { T tmpVo = (T)func.Invoke(null, new object[] { nodeList[i] }); list.Add(tmpVo); i++; } return list; }
模型类如下:
///模型类和XML文件中一个节点的数据进行对应 public class RoleVo { private int id; private string name; private int age; public int ID { get { return id; } set { id = value; } } public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public static RoleVo Parse(XmlNode node) { RoleVo vo = new RoleVo(); vo.ID = int.Parse(node.Attributes["id"].Value.ToString()); vo.Age = int.Parse(node.Attributes["age"].Value.ToString()); vo.Name = node.Attributes["name"].Value.ToString(); return vo; } }
二、当节点相互嵌套时,例如下面的XML文件内容,这是需要利用到一个递归的思想,循环获取才能得到所有的XML节点,XMl代码和C#代码如下:
<Item> <Item> <Item id="101" hp="100" att="20" name="史莱姆"/> </Item> <Item> <Item id="102" hp="120" att="25" name="哥布林"/> </Item> <Item> <Item id="103" hp="140" att="50" name="泰勒"/> </Item> <Item> <Item id="104" hp="160" att="75" name="扎西"/> </Item> </Item>
递归获取所有节点:
/// <summary> /// 获取父节点下所有的子节点(当总父节点下其他节点也存在另外的父节点时) /// </summary> /// <param name="path">xml文件所在的路径</param> /// <returns></returns> public List<XmlNode> GetXmlNodeList(string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); XmlNode parentNode = doc.FirstChild; List<XmlNode> ListNode = new List<XmlNode>(); if (parentNode.HasChildNodes) { int i = 0; while (i<parentNode.ChildNodes.Count) { GetXmlNodeInChild(parentNode.ChildNodes[i],ref ListNode); i++; } } return ListNode; } /// <summary> /// 递归获取所有的子节点 /// </summary> /// <param name="childNode"></param> /// <param name="list"></param> public void GetXmlNodeInChild(XmlNode childNode,ref List<XmlNode> list) { if (childNode.HasChildNodes) { int i = 0; while (i<childNode.ChildNodes.Count) { GetXmlNodeInChild(childNode.ChildNodes[i], ref list); i++; } } else { list.Add(childNode); } }
模型类如下:
public class EnemyVo { private int id; private int hp; private int att; private string name; public int ID { get { return id; } set { id = value; } } public int HP { get { return hp; } set { hp = value; } } public int Att { get { return att; } set { att = value; } } public string Name { get { return name; } set { name = value; } } public static EnemyVo Parse(XmlNode node) { EnemyVo vo = new EnemyVo(); vo.ID = int.Parse(node.Attributes["id"].Value.ToString()); vo.HP = int.Parse(node.Attributes["hp"].Value.ToString()); vo.Att = int.Parse(node.Attributes["att"].Value.ToString()); vo.name = node.Attributes["name"].Value.ToString(); return vo; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!