自己动手设计代码编辑器——(六)自己写XML管理类

由于C# XML的管理类没怎么看明白,自己写了实用。
首先是节点UDataElement,是XML数据中的一个节点
节点又可以包含节点。嵌套的包含。
还可以添加子节点

public class UDataElement  
    {  
        public List Items { get; protected set; }  
  
        public bool HasItem  
        {  
            get  
            {  
                return Items.Count != 0;  
            }  
        }  
  
        public string Name { get; set; }  
        public string Value { get; set; }  
  
        public UDataElement()  
        {  
            this.Items = new List();  
  
            this.Name = string.Empty;  
            this.Value = string.Empty;  
        }  
  
        public virtual void SetData(string name, string value)  
        {  
            foreach (UDataElement element in Items)  
            {  
                if (element.Name == name)  
                {  
                    element.Value = value;  
                }  
            }  
        }  
  
        public virtual void AddData(string name, string value)  
        {  
            UDataElement ue = new UDataElement();  
            ue.Name = name;  
            ue.Value = value;  
  
            Items.Add(ue);  
        }

接下来是文档分析类,作用是分析XML文档(自己定义的格式)

public class UDataParser  
    {  
        private List mData;  
        private int mRow;  
        private int mCol;  
        private int mOldRow;  
        private int mOldCol;  
  
        private int mSaveRow;  
        private int mSaveCol;  
        private int mSaveOldRow;  
        private int mSaveOldCol;  
  
        private bool mEndOfData;  
  
        public UDataParser()  
        {  
            this.mData = new List();  
            this.mRow = 0;  
            this.mCol = 0;  
            this.mOldRow = 0;  
            this.mOldCol = 0;  
            this.mEndOfData = false;  
        }  
  
        public void Load(string filePath)  
        {  
            try  
            {  
                StreamReader fp = new StreamReader(filePath, Encoding.Default);  
                string line = string.Empty;  
  
                while (!fp.EndOfStream)  
                {  
                    line = fp.ReadLine();  
  
                    if (line == string.Empty)  
                    {  
                        continue;  
                    }  
  
                    mData.Add(line);  
                }  
  
                fp.Close();  
                fp.Dispose();  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
        }  
  
        public string GetNextData()  
        {  
            StringBuilder result = new StringBuilder();  
            bool inString = false;  
  
            while (!mEndOfData)  
            {  
                char ch = GetNextChar();  
  
                if (ch == (char)0)  
                {  
                    break;  
                }  
  
                switch (ch)  
                {  
                    case '<':  
                    case '>':  
                    case '[':  
                    case ']':  
                    case ' ':  
                    case '=':  
                    case '/':  
                        if (inString)  
                        {  
                            result.Append(ch);  
                        }  
                        else  
                        {  
                            if (result.Length == 0)  
                            {  
                                return ch.ToString();  
                            }  
                            else  
                            {  
                                BackToLast();  
  
                                if (result[0] == '"')  
                                {  
                                    result.Remove(0, 1);  
                                }  
                                if (result[result.Length - 1] == '"')  
                                {  
                                    result.Remove(result.Length - 1, 1);  
                                }  
  
                                return result.ToString();  
                            }  
                        }  
                        break;  
                    case '\t':  
                        break;  
                    case '\n':  
                        break;  
                    case '"':  
                        inString = !inString;  
                        result.Append(ch);  
                        break;  
                    case '\\':  
                        result.Append(GetNextChar());  
                        break;  
                    default:  
                        result.Append(ch);  
                        break;  
                }  
            }  
  
            return result.ToString();  
        }  
  
        public string GetNextData(string data)  
        {  
            string str = GetNextData();  
  
            if (str == data)  
            {  
                return str;  
            }  
  
            throw new Exception("Unexpect " + data);  
        }  
  
        public string PeekNextData()  
        {  
            int col = mCol;  
            int row = mRow;  
            int oldCol = mOldCol;  
            int oldRow = mOldRow;  
  
            string data = GetNextData();  
  
            mCol = col;  
            mRow = row;  
            mOldCol = oldCol;  
            mOldRow = oldRow;  
  
            return data;  
        }  
  
        public void Save()  
        {  
            mSaveCol = mCol;  
            mSaveRow = mRow;  
            mSaveOldCol = mOldCol;  
            mSaveOldRow = mOldRow;  
        }  
  
        public void Load()  
        {  
            mCol = mSaveCol;  
            mRow = mSaveRow;  
            mOldCol = mSaveOldCol;  
            mOldRow = mSaveOldRow;  
        }  
  
        private char GetNextChar()  
        {  
            if (mEndOfData)  
            {  
                return (char)0;  
            }  
  
            mOldCol = mCol;  
            mOldRow = mRow;  
  
            if (mRow >= mData.Count)  
            {  
                mEndOfData = true;  
                return (char)0;  
            }  
  
            if (mCol >= mData[mRow].Length)  
            {  
                mCol = 0;  
                mRow++;  
  
                if (mRow >= mData.Count)  
                {  
                    mEndOfData = true;  
                    return (char)0;  
                }  
            }  
  
            return mData[mRow][mCol++];  
        }  
  
        private void BackToLast()  
        {  
            mCol = mOldCol;  
            mRow = mOldRow;  
        }  
    }

接下来是XML文档 UDataDocument,可以保存,载入文档。。。

public class UDataDocument : UDataElement  
    {  
        private UDataParser mParser;  
  
        public UDataDocument()  
        {  
            this.mParser = new UDataParser();  
        }  
  
        public void Load(string filePath)  
        {  
            mParser.Load(filePath);  
  
            UDataElement Environment = ParseElement();  
            UDataElement Editor = ParseElement();  
            UDataElement Language = ParseElement();  
  
            Items.Add(Environment);  
            Items.Add(Editor);  
            Items.Add(Language);  
        }  
  
        public void Save(string filePath)  
        {  
            try  
            {  
                StreamWriter fp = new StreamWriter(filePath, false, Encoding.Default);  
  
                SaveElement(fp, this, 0);  
  
                fp.Close();  
                fp.Dispose();  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
        }  
  
        private UDataElement ParseElement()  
        {  
            try  
            {  
                UDataElement element = new UDataElement();  
  
                mParser.GetNextData("[");  
  
                element.Name = mParser.GetNextData();  
                element.Value = string.Empty;  
  
                mParser.GetNextData("]");  
  
                while (true)  
                {  
                    string nextData = mParser.PeekNextData();  
  
                    switch (nextData)  
                    {  
                        case "<":  
                            {  
                                UDataElement de = new UDataElement();  
                                mParser.GetNextData("<");  
                                mParser.GetNextData("Name");  
                                mParser.GetNextData("=");  
                                de.Name = mParser.GetNextData();  
                                mParser.GetNextData(" ");  
                                mParser.GetNextData("Value");  
                                mParser.GetNextData("=");  
                                de.Value = mParser.GetNextData();  
                                mParser.GetNextData(">");  
  
                                element.Items.Add(de);  
                            }  
                            break;  
                        case "[":  
                            mParser.Save();  
  
                            mParser.GetNextData("[");  
  
                            if (mParser.PeekNextData() == "/")  
                            {  
                                mParser.GetNextData("/");  
                                mParser.GetNextData(element.Name);  
                                mParser.GetNextData("]");  
  
                                return element;  
                            }  
                            else  
                            {  
                                mParser.Load();  
                                element.Items.Add(ParseElement());  
                            }  
  
                            break;  
                        default:  
                            break;  
                    }  
                }  
  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
        }  
  
        private void SaveElement(StreamWriter fp, UDataElement element, int tab)  
        {  
            try  
            {  
                foreach (UDataElement ue in element.Items)  
                {  
                    for (int i = 0; i < tab; i++)  
                    {  
                        fp.Write('\t');  
                    }  
  
                    if (ue.HasItem)  
                    {  
                        fp.WriteLine("[" + ue.Name + "]");  
  
                        SaveElement(fp, ue, tab + 1);  
  
                        for (int i = 0; i < tab; i++)  
                        {  
                            fp.Write('\t');  
                        }  
  
                        fp.WriteLine("[/" + ue.Name + "]");  
                        fp.WriteLine();  
                    }  
                    else  
                    {  
                        fp.WriteLine("");  
                    }  
                }  
            }  
            catch (Exception ex)  
            {  
                throw ex;  
            }  
        }  
    }

自定义XML格式如下

    [Environment]  
          
    [/Environment]  
      
    [Editor]  
          
          
          
          
          
          
          
          
          
          
          
    [/Editor]  
      
    [Language]  
        [C#]  
              
        [/C#]  
    [/Language]  

你可能感兴趣的:(自己动手设计代码编辑器——(六)自己写XML管理类)