WPF开发较为完整的音乐播放器(二) ---Xml读取类的构建
在昨天的文章中,讲述了开发音乐播放器的第一步之播放类的构建,今天的文章就开始第二步--Xml读取类的构建。
一个音乐播放器是要有列表文件的,这里就用Xml文件作为列表文件。
为了读取音乐列表更方便,我们将这方面的操作封装成一个专门的类,名曰MusicListsReaders类。
在构建类之前,先讲一些关于Xml的基础知识。
一是XmlDocument类,它表示一个XML 文档。可以用其中的Load方法加载一个Xml文件,在进行各种操作。可以参考msdn上的文章http://msdn.microsoft.com/zh-cn/library/system.xml.xmldocument.aspx;
二是XmlNode类,它表示 XML 文档中的单个节点。其中的重要属性是InnerText(表示节点中的文本)和ChildNodes属性(表示节点下的所有子节点),重要方法则有SelectNodes(获取指定的节点集合[获取多个]和SelectSingleNode(获取指定的节点[获取第一个])。
三是XmlElement类,它表示一个元素。除包含以上介绍的XmlNode具有的重要属性和重要方法外,还有一个重要的方法GetAttribute,它返回返回具有指定名称的特性的值。具体是什么意思呢,例如这里有一个Xml文件:
<Root> <Numbers> <Number id="1"></Number> </Numbers> </Root>
这是一个最简单的Xml文件,其中节点 Root 叫做根节点,它里面的节点叫做子节点,下层的是上层的子节点,其中的id="1",就是具有指定名称的特征的值。
以上只介绍了我们在下边会用到的方法及属性,并不包含全部,具体请MSDN。
新建一个类文件,在类的开头声明几个私有变量:
private string url; //表示列表(Xml)文件路径
private XmlDocument dom; //表示Xml文档
private bool isError=false; //表示是否有错误
private string errorText=""; //表示错误信息
现在开始编写构造函数,和上一个类一样,都是有两个构造函数,方便用不同的方式传入列表(xml)文件的路径:
/// <summary> /// 构造函数 /// </summary> /// <param name="filename">音乐列表文件名</param> public MusicListsReader(string filename) { dom = new XmlDocument(); LoadXml(filename); } /// <summary> /// 构造函数重载+1 /// </summary> public MusicListsReader() { dom = new XmlDocument(); }
以下是LoadXml的方法实现:
/// <summary> /// 载入指定的音乐列表xml文件 /// </summary> /// <param name="filename">音乐列表文件名</param> public void LoadXml(string filename) { if (url == "") { SetErrorInformation("亲,列表读取错误!"); } url = filename; dom.Load(url); }
这是SetErrorInformation和GetErrorInformation方法的实现:
/// <summary> /// 设置列表错误信息 /// </summary> /// <param name="errortext"></param> /// <returns></returns> public void SetErrorInformation(string errortext) { isError = true; errorText =errortext; }
/// <summary> /// 获取列表错误信息 /// </summary> /// <returns></returns> public string GetErrorInformation() { if (isError == true) { return errorText; } else { return null; } }
再展示下其余的代码,相信大家完全可以看明白:
/// <summary> /// 获取文档根节点 /// </summary> /// <returns></returns> private XmlElement GetXmlRootElement() { return dom.DocumentElement; } /// <summary> /// 获取列表的名称 /// </summary> public string GetXmlMusicListName() { XmlElement root=GetXmlRootElement(); return GetAttribute(root, "name"); } /// <summary> /// 获取xml文件中所有的音乐子项 /// </summary> /// <returns></returns> public XmlNodeList GetXmlMusicItems() { XmlElement root= GetXmlRootElement();//获取根节点 XmlNode rootn = XmlConverter(root);//转换为XmlNode return rootn.SelectNodes("Music");//选定返回所有Music节点 } /// <summary> /// 获取列表中的音乐总数 /// </summary> /// <returns></returns> public int GetXmlCount() { XmlElement xe= GetXmlRootElement(); return xe.ChildNodes.Count; } /// <summary> /// 获取指定元素的值 /// </summary> /// <param name="xe"></param> /// <param name="attribute">XmlElement对象</param> /// <returns></returns> public string GetAttribute(XmlElement xe, string attribute) { return xe.GetAttribute(attribute);//返回该Attribute的值 } /// <summary> /// 获取指定歌曲的url /// </summary> /// <param name="xe">XmlElement对象</param> /// <returns></returns> public string GetMusicUrl(XmlElement xe) { return GetAttribute(xe, "url"); } /// <summary> /// 获取指定歌曲的歌手 /// </summary> /// <param name="xe">XmlElement对象</param> /// <returns></returns> public string GetMusicSinger(XmlElement xe) { return GetAttribute(xe, "singer"); } /// <summary> /// 获取指定歌曲的名称 /// </summary> /// <param name="xe">XmlElement对象</param> /// <returns></returns> public string GetMusicName(XmlElement xe) { return xe.InnerText; } /// <summary> /// 获取指定音乐节点 /// </summary> /// <param name="index">序号</param> /// <returns>返回XmlNode对象</returns> private XmlNode GetXmlMusicItemByIndex(int index) { XmlNodeList xnl = GetXmlMusicItems(); return xnl.Item(index); } /// <summary> /// 获取指定音乐节点的所有信息 /// </summary> /// <param name="index">序号</param> /// <returns>返回XmlListProduct对象</returns> public XmlListProduct GetXmlMusicItemInformation(int index) { XmlNode xn= GetXmlMusicItemByIndex(index); XmlElement xe = XmlConverter(xn); XmlListProduct xlp= new XmlListProduct(GetMusicUrl(xe),GetMusicName(xe), GetMusicSinger(xe)); return xlp; } /// <summary> /// 将XmlElement转换为XmlNode /// </summary> /// <param name="xe">要转换的XmlElement</param> /// <returns></returns> private XmlNode XmlConverter(XmlElement xe) { return (XmlNode)xe; } /// <summary> /// 将XmlNode转换为XmlElement /// </summary> /// <param name="xn">要转换的XmlNode</param> /// <returns></returns> private XmlElement XmlConverter(XmlNode xn) { return (XmlElement)xn; } }
由于XmlNode和XmlElement经常需要转换,就在上边的代码中写了个重载函数,方便转换。
以上只是对代码的封装,便于操作,涉及到的知识并是不很多。至此今天的文章到此结束。
在明天的文章中将会构建数据读取类,为数据绑定做基础的。
希望大家拍砖别拍的太狠哈。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架