C#读取XML文件——自定义类

来源:互联网 发布:qq浏览器mac版什么内核 编辑:程序博客网 时间:2024/06/07 20:59

C#本身也带有读取XML文件的类,但是许久未曾接触C#了,为了练练手,自己写了一个具有简单功能的类,实现了读取xml文件,查找元素,插入结点等功能。实现如下:

XmlDoc类

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;namespace ConsoleCSharp{    class XmlDoc    {        internal static string xmlStr = string.Empty;        private XmlNode root = new XmlNode();        private string remark = string.Empty;        public static List<XmlNode> AllNodes = new List<XmlNode>();        internal List<XmlNode> nodes = new List<XmlNode>();        public XmlNode Root        {            get { return root; }            set { root = value; }        }        public string Remark        {            get { return remark; }            set { remark = value; }        }        public XmlDoc(string path)        {            StreamReader sr = new StreamReader(path, Encoding.Default);            xmlStr = InitialXmlStr(sr.ReadToEnd());            sr.Close();            if (!VerifyXml())            {                throw new XmlInvalidException();            }            int begin = xmlStr.IndexOf("?>");            int end = xmlStr.LastIndexOf(">");            root.InitialXmlNode(begin, end);            AllNodes.Add(root);            if (!root.hasChildren())            {                AllNodes[0].setContent();            }            else            {                root.ExtractAllNode();            }        }        //初始化XML字符串        private string InitialXmlStr(string str)        {            while(str.IndexOf("< ") != -1)            {                str = str.Replace("< ","<");  //"< " --> "<"            }            //while (str.IndexOf(" <") != -1)            //{            //    str = str.Replace(" <", "<");  //" <" --> "<"            //}            while(str.IndexOf(" >") != -1)            {                str = str.Replace(" >",">");  //" >" --> ">"            }            //while (str.IndexOf("> ") != -1)            //{            //    str = str.Replace("> ", ">");  //"> " --> ">"            //}            while (str.IndexOf("/ ") != -1)            {                str = str.Replace("/ ", "/");  //"/ " --> "/"            }            return str;        }        //将XML写入到文本文件中        public static void WriteToFile(string path)        {            StreamWriter sw = new StreamWriter(path);            sw.Write(XmlDoc.xmlStr);            sw.Flush();            sw.Close();        }        //验证XML文件的有效性        private bool VerifyXml()        {            int i = xmlStr.IndexOf("<?");            int j = -1;            if (i != -1)            {                j = xmlStr.IndexOf("?>");                if (j == -1)                {                    return false;                }            }            if (i != -1 && j != -1)            {                int v = xmlStr.IndexOf("version");                int m = -1, n = -1;                if (v != -1)                {                    m = xmlStr.IndexOf("\"", i, j - i + 1);                    n = xmlStr.IndexOf("\"", m + 1, j - m);                    if (m == -1 || n == -1)                    {                        return false;                    }                    string version = xmlStr.Substring(m + 1, n - m - 1);                    remark += "version:" + version;                }                int e = xmlStr.IndexOf("encoding");                if (e != -1)                {                    if (n != -1)                    {                        m = xmlStr.IndexOf("\"", n + 1, j - n);                        n = xmlStr.IndexOf("\"", m + 1, j - m);                        if (m == -1 || n == -1)                        {                            return false;                        }                        string encoding = xmlStr.Substring(m + 1, n - m - 1);                        remark += " encoding:" + encoding;                    }                    else                    {                        m = xmlStr.IndexOf("\"", e, j - n - 1);                        n = xmlStr.IndexOf("\"", e, j - m - 1);                        if (m == -1 || n == -1)                        {                            return false;                        }                        string encoding = xmlStr.Substring(m + 1, n - m - 1);                        remark += " encoding:" + encoding;                    }                }            }            return true;        }        //将文档转化为字符串        public override string ToString()        {            StringBuilder sb = new StringBuilder();            for (int i = 0; i < XmlDoc.AllNodes.Count; i++)            {                if (XmlDoc.AllNodes[i].Depth() == 2)                {                    sb.Append(XmlDoc.AllNodes[i].ToString());                    sb.Append("\n");                }            }            return sb.ToString();        }        //根据元素名称查找元素        public List<XmlNode> GetElementsByTagName(string name)        {            nodes.Clear();            foreach(XmlNode node in AllNodes)            {                if (String.Compare(node.Name,name) == 0)                {                    nodes.Add(node);                }            }            return nodes;        }    }    class XmlInvalidException : Exception    {        private string message;        public override string Message        {            get { return message; }        }        public XmlInvalidException()        {            this.message = "XML FILE INVALID!";        }        public XmlInvalidException(string str)        {            this.message = str;        }    }}

XMLNode类

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleCSharp{    public class NodeAttribute    {        public string Name = string.Empty;        public string Content = string.Empty;        public NodeAttribute()        {        }        public NodeAttribute(string name, string content)        {            this.Name = name;            this.Content = content;        }    }    class XmlNode    {        private string name = string.Empty;        private string content = string.Empty;        private NodeAttribute attribute = new NodeAttribute();        internal int startindex1 = -1;        internal int startindex2 = -1;        internal int endindex1 = -1;        internal int endindex2 = -1;        internal string startMarker = string.Empty;        internal string endMarker = string.Empty;        internal bool hasChild = false; //是否有子元素        private bool hasNext = false; //是否有兄弟元素        private List<XmlNode> nodes = new List<XmlNode>();        internal XmlNode father;        public string Name        {            get { return name; }            set             {                this.name = value;                this.startMarker = "<" + this.name + ">";                this.endMarker = "</" + this.name + ">";            }        }        public NodeAttribute Attribute        {            get { return attribute; }            set { attribute = value; }        }        //获取元素的内容        public string Content        {            get { return content; }            set { content = value; }        }        //获取元素的子元素        public List<XmlNode> Nodes        {            get { return nodes; }            set { nodes = value; }        }        //提取该元素的所有子元素        internal void ExtractAllNode()        {            XmlNode node = this;            if (node.hasChildren())            {                node.GetChildren();                for (int i = 0; i < node.Nodes.Count; i++ )                {                    node.Nodes[i].ExtractAllNode();                }            }            else            {                node.setContent();            }        }        //提取元素的下一层元素        private void GetChildren()        {            XmlNode node = this;            int begin = node.startindex2 + 1;            int end = node.endindex1 - 1;            XmlNode newnode = new XmlNode();            newnode.father = node;            newnode.InitialXmlNode(begin, end);            node.nodes.Add(newnode);            XmlDoc.AllNodes.Add(newnode);            newnode.GetBrothers();        }        //提取该元素之后的所有兄弟元素        private void GetBrothers()        {            XmlNode node = this;            while (node.hasNextBrother())            {                int begin = node.endindex2 + 1;                int end = node.father.endindex1 - 1;                XmlNode newnode = new XmlNode();                newnode.father = node.father;                newnode.InitialXmlNode(begin, end);                node.father.nodes.Add(newnode);                XmlDoc.AllNodes.Add(newnode);                node = newnode;            }        }        //判断元素是否有子元素        internal bool hasChildren()        {            int begin = this.startindex2 + 1;            int end = this.endindex1 - 1;            int index = XmlDoc.xmlStr.IndexOf("<", begin, end - begin + 1);            if (index != -1)            {                this.hasChild = true;                return true;            }            return false;        }        //判断元素是否还有下一个兄弟元素        internal bool hasNextBrother()        {            int begin = this.endindex2 + 1;            if (this.father == null)            {                return false;            }            int end = this.father.endindex1 - 1;            int index = XmlDoc.xmlStr.IndexOf("<", begin, end - begin + 1);            if (index != -1)            {                this.hasNext = true;                return true;            }            return false;        }        //设置元素的内容        internal void setContent()        {            if (this.hasChildren())            {                return;            }            this.Content = XmlDoc.xmlStr.Substring(this.startindex2 + 1, this.endindex1 - this.startindex2 - 1).Trim();        }        /// <summary>        /// 根据元素在字符串中的起始索引和结束索引设置元素的字段信息        /// </summary>        /// <param name="begin">初始索引</param>        /// <param name="end">结束索引</param>        internal void InitialXmlNode(int begin, int end)        {            this.startindex1 = XmlDoc.xmlStr.IndexOf("<", begin, end - begin + 1);            this.startindex2 = XmlDoc.xmlStr.IndexOf(">", this.startindex1 + 1, end - startindex1);            if (this.startindex1 == -1 || this.startindex2 == -1)            {                throw new XmlInvalidException();            }            int temp = XmlDoc.xmlStr.IndexOf(" ", this.startindex1, this.startindex2 - this.startindex1 + 1);            if (temp != -1)            {                this.startMarker = XmlDoc.xmlStr.Substring(this.startindex1, temp - this.startindex1 + 1).Trim() + ">";                this.InitialNodeAttribute(this.startindex1, this.startindex2);            }            else            {                this.startMarker = XmlDoc.xmlStr.Substring(this.startindex1, this.startindex2 - this.startindex1 + 1);            }                        this.name = this.startMarker.Substring(1, this.startMarker.Length - 2).Trim();            //this.endMarker = this.startMarker.Replace("<", "</");            this.endMarker = "</" + this.name + ">";            this.endindex1 = XmlDoc.xmlStr.IndexOf(this.endMarker, this.startindex2 + 1);            if (this.endindex1 == -1)            {                throw new XmlInvalidException(string.Format("没有匹配的元素尾:{0}", this.endMarker));            }            this.endindex2 = this.endindex1 + this.endMarker.Length - 1;        }        /// <summary>        /// 根据元素头在字符串中的起始索引和终止索引设置元素的属性        /// </summary>        /// <param name="begin"></param>        /// <param name="end"></param>        private void InitialNodeAttribute(int begin, int end)        {            int cbegin = XmlDoc.xmlStr.IndexOf("\"", begin, end - begin + 1) + 1;            int cend = XmlDoc.xmlStr.IndexOf("\"", cbegin, end - cbegin + 1) - 1;            int equal = XmlDoc.xmlStr.LastIndexOf("=", end, end - begin + 1);            int nbegin = XmlDoc.xmlStr.IndexOf(" ", begin, equal - begin + 1);            int nend = XmlDoc.xmlStr.IndexOf(" ", nbegin + 1, equal - nbegin);            nend = nend == -1 ? equal - 1 : nend; //属性等号之前无空格            this.attribute.Name = XmlDoc.xmlStr.Substring(nbegin, nend - nbegin + 1).Trim();            this.attribute.Content = XmlDoc.xmlStr.Substring(cbegin, cend - cbegin + 1).Trim();        }        //用于输出格式化结点        public override string ToString()        {            string str = "";            int deep = this.Depth();                        //深度大于2的元素,只显示子元素名称,不显示具体内容            if (deep > 2)            {                for (int i = 0; i < this.Nodes.Count; i++)                {                    str += "{" + this.Nodes[i].Name + "}";                }            }            else if (deep == 2) //深度等于2的元素,显示所有子元素的名称及其内容            {                for (int i = 0; i < this.Nodes.Count; i++)                {                    str += this.Nodes[i].Name + ":" + this.Nodes[i].Content + "\t";                }                if (this.Attribute.Name != "")                {                    str += this.Attribute.Name + ":" + this.Attribute.Content;                }            }            else  //深度等于1的元素,显元素的名称及其内容            {                return this.Name + ":" + this.Content;            }            return str;        }        //获取元素的深度,没有子元素的深度为1        internal int Depth()        {            if (!this.hasChild)            {                return 1;            }            else            {                int max = 1;                for (int i = 0; i < this.Nodes.Count; i++ )                {                    int deep = this.Nodes[i].Depth() + 1;                    max = max > deep ? max : deep;                }                return max;            }        }        //添加子元素        public void AppendChild(XmlNode node)        {            string str = node.StringXML();            node.father = this;            this.Nodes.Add(node);            XmlDoc.xmlStr = XmlDoc.xmlStr.Insert(this.startindex2 + 1, "\r\n" + str);        }        //获取结点的字符串表示形式        private string StringXML()        {            StringBuilder sb = new StringBuilder();            sb.Append(this.startMarker + this.Content + this.endMarker);            if (this.Attribute.Name != "")            {                string temp = string.Format("{0} {1}=\"{2}\">",                    this.startMarker.Substring(0, this.startMarker.Length - 1),                    this.Attribute.Name,                    this.Attribute.Content);                sb.Replace(this.startMarker, temp);            }            return sb.ToString();        }    }}

主函数

        static void Main(string[] args)        {            try            {                XmlDoc xml = new XmlDoc(@"C:\Users\Administrator\Desktop\testdata.txt");                Console.WriteLine("XML声明信息:");                Console.WriteLine(xml.Remark);                Console.WriteLine("\n输出单个结点的信息:");                Console.WriteLine(xml.Root.Nodes[0].Nodes[0].Content);                Console.WriteLine(xml.Root.Nodes[0].ToString());                Console.WriteLine(xml.Root.Nodes[1].ToString());                Console.WriteLine(xml.Root.Nodes[2].ToString());                Console.WriteLine("\n输出XML文档所有(深度为2)结点的信息:");                Console.Write(xml.ToString());                Console.WriteLine("\n输出根据名字查找到的元素:");                List<XmlNode> nodes = xml.GetElementsByTagName("author");                foreach (XmlNode node in nodes)                {                    Console.WriteLine(node.ToString());                }                string path = @"C:\Users\Administrator\Desktop\tt.txt";                XmlNode newnode = new XmlNode();                newnode.Name = "XXX";                newnode.Content = "YYY";                newnode.Attribute = new NodeAttribute("attributeName", "attributeValue");                xml.Root.AppendChild(newnode);                XmlDoc.WriteToFile(path);                Console.ReadKey();            }            catch (Exception e)            {                Console.WriteLine(e.Message);            }        }

测试结果:

输入:


输出:



0 0