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

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);
            }
        }

测试结果:

输入:

输出:

转自:http://blog.csdn.net/foreverling/article/details/43458467

时间: 2025-01-01 19:06:14

C#读取XML文件——自定义类的相关文章

一个读取xml文件内容的类

xml 一个读取xml文件内容的类 package project.util.xml; import java.io.*;import java.util.*;import javax.servlet.http.*;import org.apache.log4j.*;import org.jdom.*;import org.jdom.input.*; /*** <p>Title: <font color="steelblue" size="10"&

php中使用DOM类读取XML文件的实现代码_php技巧

主要功能:php中使用DOM类读取XML文件 设计知识点: 1.XML节点循环读取 2.用iconv()函数实现编码转换,防止中文乱码 holiday.xml文件如下 复制代码 代码如下: <?xml version="1.0" encoding="UTF-8"?> <daysOff-overTime> <year> <yearName>2012</yearName> <holiday> <

java实现利用String类的简单方法读取xml文件中某个标签中的内容_java

1.利用String类提供的indexOf()和substring()快速的获得某个文件中的特定内容 public static void main(String[] args) { // 测试某个词出现的位置 String reqMessage = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + "<in>" + "<head&g

利用SAX解析读取XML文件

xml     这是我的第一个BLOG,今天在看<J2EE应用开发详解>一书,书中讲到XML编程,于是就按照书中的步骤自己测试了起来,可是怎么测试都不成功,后来自己查看了一遍源码,发现在读取XML文件的位置时有误,于是进行了更改,还真行了,心中涌出一中成就感,现将源码贴出来与给位分享: 使用XML文件连接MYSQL数据库,database.conf.xml文件如下: <database-conf><datasource> <driver>com.mysql.

利用缓存机制快速读取XML文件中的数据

xml|缓存|数据 接到一个任务,让我做一个公司网站的后台管理系统.要求很简单,就一个新闻发布模块和一个招聘信息发布模块.但不能用DB,只能用文件存取的形式实现.        不用考虑肯定是用XML文件进行数据的存取了,以前做毕设的时候也曾经实现过类似的功能,所以关于XML的读取并没有问题.关键是如果考虑到性能的问题就值得推敲一下了,我是新人,以前也没做过什么设计,所以做出的东西在一些人眼中可能会有些稚嫩,那也没关系,走自己的路让别人去说吧:)        如果频繁解析文件,速度肯定受到影响

XMLTextReader和XmlDocument读取XML文件的比较

xml|比较 看到网上一片文章,自己式了一下,果然 XMLTextReader速度要快! 在.NET框架的System.XML名称空间中包含的XMLTextReader类不需要对系统资源要求很高,就能从XML文件中快速读取数据.使用XMLTextReader类能够从XML文件中读取数据,并且将其转换为HTML格式在浏览器中输出.   读本文之前,读者需要了解一些基本知识:XML.HTML.C#编程语言,以及.NET尤其是ASP.NET框架的一些知识. 微软公司的.NET框架为开发者提供了许多开发

php类:XML文件分析类

XMLParser.class.php <?php /** XML 文件分析类 * Date: 2013-02-01 * Author: fdipzone * Ver: 1.0 * * func: * loadXmlFile($xmlfile) 读入xml文件输出Array * loadXmlString($xmlstring) 读入xmlstring 输出Array */ class XMLParser{ /** 读取xml文件 * @param String $xmlfile * @retu

php的XML文件解释类应用实例

 XMLParser.class.php类文件如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 7

Extjs读取xml文件生成动态表格和表单(续)

很多人向我要[Extjs读取xml文件生成动态表格和表单]一文的源代码,故花了些时间将源代码整理出来,并重新编写此文,分享当时的技术思路. 需要的文件有: 1.html文件,此处以SASC.search.MtrUse.html为例 2.Extjs相关文件,见SASC.search.MtrUse.html文件中的引用 3.工具类,DomUtils.js 4.核心js类:SASC.extjs.search.MtrUse.js 5.java代码 详细html和js代码见相关文件,这里先描述思路. 首先