//--------------------------日期:2017-04-07
//--------------------------版本:2.0.0 .0
//--------------------------作者:itrycn
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
//XML存储类
namespace ryCommon
{
    /// <summary>
    /// XML操作类
    /// </summary>
    public class Storage
    {
        private XmlDocument xmlDoc = new XmlDocument();
        private XmlNode xmlNode;
        private XmlElement element;
        //private System.Xml.XmlNodeList NodeList2;
        /// <summary>
        /// XML操作类
        /// </summary>
        public Storage()
        {
            string strXMLText = "<root></root>";
            xmlDoc.LoadXml(strXMLText);
        }
        /// <summary>
        /// 从XML文本中加载数据
        /// </summary>
        /// <param name="XMLText"></param>
        public Storage(string XMLText) //从XML文本中加载数据
        {
            try
            {
                xmlDoc.LoadXml(XMLText);
            }
            catch
            {
                xmlDoc.LoadXml("<root></root>");
            }
        }
        #region 从指定的XML文本中加载
        /// <summary>
        /// 从指定的XML文本中加载
        /// </summary>
        /// <param name="XMLText">XML文本</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int LoadFromXMLText(string XMLText)
        {
            try
            {
                xmlDoc.LoadXml(XMLText);
                return 1;
            }
            catch
            {
                xmlDoc.LoadXml("<root></root>");
                return 0;
            }
        }
        #endregion
        #region 加载空的XML文本
        /// <summary>
        /// 载入空的XML文档
        /// </summary>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int LoadEmptyXMLText()
        {
            try
            {
                xmlDoc.LoadXml("<root></root>");
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 从指定的文件中加载
        /// <summary>
        /// 从指定的文件中加载
        /// </summary>
        /// <param name="FilePath">XML文件路径</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int LoadFromFile(string FilePath)
        {
            try
            {
                xmlDoc.Load(FilePath);
                return 1;
            }
            catch
            {
                xmlDoc.LoadXml("<root></root>");
                return 0;
            }
        }
        #endregion
        #region 保存到指定文件中
        /// <summary>
        /// 保存到指定文件中
        /// </summary>
        /// <param name="sFilePath">文件路径</param>
        /// <returns>如为1，表示保存成功，为0为失败</returns>
        public int SaveToFile(string sFilePath)
        {
            try
            {
                if (sFilePath != "" && !System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(sFilePath)))
                {
                    System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(sFilePath));
                }
                xmlDoc.Save(sFilePath);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 判断节点是否存在
        /// <summary>
        /// 判断节点是否存在  
        /// </summary>
        /// <param name="AttrName">属性名</param>
        /// <param name="sValue">属性值</param>
        /// <returns>返回1，表示存在，其它表示不存在</returns>
        public int HaveNode(string AttrName, string sValue)
        {
            try
            {
                //根据指定路径获取节点
                XmlNode xmlNode2 = null;
                xmlNode2 = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']");
                if (xmlNode2 == null)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 定位节点
        /// <summary>
        /// 定位节点  
        /// </summary>
        /// <param name="AttrName">属性名</param>
        /// <param name="sValue">属性值</param>
        /// <returns>返回第一个符合要求的结果</returns>
        public int SelectNode(string AttrName, string sValue)
        {
            try
            {
                //根据指定路径获取节点
                element = null;
                xmlNode = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']");
                element = (XmlElement)xmlNode;
                if (element == null)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 定位节点2
        /// <summary>
        /// 定位节点,如果找不到节点，就新建一个节点
        /// </summary>
        /// <param name="AttrName">属性名</param>
        /// <param name="sValue">属性值</param>
        /// <returns>返回第一个符合要求的结果</returns>
        public int SelectNode2(string AttrName, string sValue)
        {
            try
            {
                //根据指定路径获取节点
                element = null;
                xmlNode = xmlDoc.SelectSingleNode("root/list[@" + AttrName + "='" + sValue + "']");
                element = (XmlElement)xmlNode;
                if (element == null)
                {
                    return AddNode2(AttrName, sValue);
                }
                else
                {
                    return 1;
                }
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 定位节点3
        /// <summary>
        /// 根据用户的节点定位节点，输入节点时，一定要注意节点是属于类内部的，否则可能出错。
        /// </summary>
        /// <returns>返回第一个符合要求的结果</returns>
        public int SelectNode3(XmlNode m_xmlNode)
        {
            try
            {
                //根据指定路径获取节点
                element = null;
                xmlNode = m_xmlNode;
                element = (XmlElement)xmlNode;
                if (element == null)
                {
                    return 0;
                }
                else
                {
                    return 1;
                }
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 定位设置节点
        /// <summary>
        /// 定位设置节点
        /// </summary>
        /// <returns>返回第一个符合要求的结果</returns>
        public int SelectNodeBySet()
        {
            return SelectNode2("id", "Setting");
        }
        /// <summary>
        /// 在节点后插入数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public XmlNode InsertAfter(int index)
        {
            XmlNode root = xmlDoc.SelectSingleNode("root");
            XmlNode refChild = xmlDoc.SelectSingleNode("root//list[" + index + "]");
            return root.InsertAfter(xmlNode, refChild);
        }
        /// <summary>
        /// 在节点前插入数据
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public XmlNode InsertBefore(int index)
        {
            XmlNode root = xmlDoc.SelectSingleNode("root");
            XmlNode refChild = xmlDoc.SelectSingleNode("root//list["+index+"]");
            return root.InsertBefore(xmlNode, refChild);
        }
        #endregion
        #region 获取节点数量
        /// <summary>
        /// 获取节点数量  
        /// </summary>
        /// <param name="AttrName">属性名</param>
        /// <param name="sValue">属性值</param>
        /// <returns>返回符合要求的结果数量</returns>
        public int GetSelectNodeCount(string AttrName, string sValue)
        {
            try
            {
                //根据指定路径获取节点
                return xmlDoc.SelectNodes("root/list[@" + AttrName + "='" + sValue + "']").Count;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 获取节点数量
        /// <summary>
        /// 获取节点数量  
        /// </summary>
        /// <returns>返回符合要求的结果数量</returns>
        public int GetNodeCount()
        {
            try
            {
                //根据指定路径获取节点
                return xmlDoc.SelectNodes("root/list").Count;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        private int ConvertInt(string str, int defValue)
        {
            try
            {
                return Convert.ToInt32(str);
            }
            catch
            {
                return defValue;
            }
        }
        #region 获取节点数量
        /// <summary>
        /// 获取节点数量  
        /// </summary>
        /// <param name="AttrName">属性名</param>
        /// <param name="sValue">属性值</param>
        /// <param name="AttrName2"></param>
        /// <param name="Relation"></param>
        /// <param name="sValue2"></param>
        /// <returns>返回符合要求的结果数量</returns>
        public int GetSelectNodeCount(string AttrName, string sValue, string AttrName2, string Relation, int sValue2)
        {
            try
            {
                //根据指定路径获取节点
                XmlNodeList nodelist = xmlDoc.SelectNodes("root/list[@" + AttrName + "='" + sValue + "']");
                int icount = 0;
                for (int i = 0; i < nodelist.Count; i++)
                {
                    XmlAttribute attr = nodelist.Item(i).Attributes[AttrName2];
                    if (attr != null)
                    {
                        switch (Relation)
                        {
                            case "<":
                                if (ConvertInt(attr.Value, 0) < sValue2)
                                {
                                    icount++;
                                }
                                break;
                            case ">":
                                if (ConvertInt(attr.Value, 0) > sValue2)
                                {
                                    icount++;
                                }
                                break;
                            case "=":
                                if (ConvertInt(attr.Value, 0) == sValue2)
                                {
                                    icount++;
                                }
                                break;
                            case "<>":
                                if (ConvertInt(attr.Value, 0) != sValue2)
                                {
                                    icount++;
                                }
                                break;
                            case ">=":
                                if (ConvertInt(attr.Value, 0) >= sValue2)
                                {
                                    icount++;
                                }
                                break;
                            case "<=":
                                if (ConvertInt(attr.Value, 0) <= sValue2)
                                {
                                    icount++;
                                }
                                break;
                        }
                    }
                }
                return icount;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, string strValue)
        {
            try
            {                //设置节点值
                element.SetAttribute(strName, strValue);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值(布尔类型)
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, bool strValue)
        {
            try
            {                //设置节点值
                string m_value = "0";
                if (strValue == true) { m_value = "1"; }
                element.SetAttribute(strName, m_value);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值(int类型)
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, int strValue)
        {
            try
            {                //设置节点值
                element.SetAttribute(strName, strValue.ToString());
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值(decimal类型)
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, decimal strValue)
        {
            try
            {                //设置节点值
                element.SetAttribute(strName, strValue.ToString());
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值(double类型)
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, double strValue)
        {
            try
            {                //设置节点值
                element.SetAttribute(strName, strValue.ToString());
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 设置节点值(日期类型)
        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="strName">属性名</param>
        /// <param name="strValue">属性值</param>
        /// <returns>如为1，表示加载成功，为0为失败</returns>
        public int SetAttrValue(string strName, DateTime strValue)
        {
            try
            {                //设置节点值
                element.SetAttribute(strName, strValue.ToDateTimeStr());
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 读取指定节点的值
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <returns></returns>
        public string GetAttrValue(string strNode)
        {
            try
            {
                if (element == null) { return ""; }
                //根据路径获取节点
                return element.GetAttribute(strNode);
            }
            catch
            {
                return "";
            }
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public string GetAttrValueByBase64(string strNode,string defValue)
        {
            try
            {
                //根据路径获取节点
                string str= element.GetAttribute(strNode);
                ryCommon.Strings cStr = new Strings();
                string base64 = cStr.Base64ToStr(str);
                if (base64 == "") { return defValue; }
                return base64;
            }
            catch
            {
                return defValue;
            }
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public bool GetAttrValue(string strNode, bool defValue)
        {
            return GetAttrValueByBool(strNode, defValue);
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public int GetAttrValue(string strNode, int defValue)
        {
            return GetAttrValueByInt(strNode, defValue);
        }
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public Int64 GetAttrValue(string strNode, Int64 defValue)
        {
            try
            {
                //根据路径获取节点
                string strTemp = element.GetAttribute(strNode);
                return Convert.ToInt64(strTemp);
            }
            catch
            {
                return defValue;
            }
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public decimal GetAttrValue(string strNode, decimal defValue)
        {
            return GetAttrValueByDecimal(strNode, defValue);
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public double GetAttrValue(string strNode, double defValue)
        {
            try
            {
                //根据路径获取节点
                string strTemp = element.GetAttribute(strNode);
                return Convert.ToDouble(strTemp);
            }
            catch
            {
                return defValue;
            }
        }
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public DateTime GetAttrValue(string strNode, DateTime defValue)
        {
            return GetAttrValueByDate(strNode, defValue);
        }
        #endregion
        #region 读取指定节点的值
        /// <summary>
        /// 读取所有的节点名称
        /// </summary>
        /// <returns></returns>
        public string[] GetAttrNames()
        {
            try
            {
                if (element == null) { return null; }
                string[] items = new string[element.Attributes.Count];
                for (int i = 0; i < items.Length; i++)
                {
                    items[i] = element.Attributes.Item(i).Name;
                }
                //根据路径获取节点
                return items;
            }
            catch
            {
                return null;
            }
        }
        #endregion
        #region 读取指定节点的值2
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public string GetAttrValue(string strNode, string defValue)
        {
            try
            {
                //根据路径获取节点
                if (element == null) { return defValue; }
                string strTemp = element.GetAttribute(strNode);
                if (strTemp == "")
                {
                    return defValue;
                }
                else
                {
                    return strTemp;
                }
            }
            catch
            {
                return defValue;
            }
        }
        #endregion
        #region 读取指定节点的值3
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public int GetAttrValueByInt(string strNode, int defValue)
        {
            try
            {
                //根据路径获取节点
                if (element == null) { return defValue; }
                string strTemp = element.GetAttribute(strNode);
                return Convert.ToInt32(strTemp);
            }
            catch
            {
                return defValue;
            }
        }
        #endregion
        #region 读取指定节点的值4
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public decimal GetAttrValueByDecimal(string strNode, decimal defValue)
        {
            try
            {
                if (element == null) { return defValue; }
                //根据路径获取节点
                string strTemp = element.GetAttribute(strNode);
                return Convert.ToDecimal(strTemp);
            }
            catch
            {
                return defValue;
            }
        }
        #endregion
        #region 读取指定节点的值5(布尔值)
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        ///  <param name="defValue"></param>
        /// <returns></returns>
        public bool GetAttrValueByBool(string strNode, bool defValue)
        {
            try
            {
                if (element == null) { return defValue; }
                //根据路径获取节点
                if (!element.HasAttribute(strNode)) { return defValue; }
                string strTemp = element.GetAttribute(strNode);
                if (strTemp == "1")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch
            {
                return defValue;
            }
        }
        #endregion
        #region 读取指定节点的值6(日期值)
        /// <summary>
        /// 读取指定节点的值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="defValue"></param>
        /// <returns></returns>
        public DateTime GetAttrValueByDate(string strNode, DateTime defValue)
        {
            try
            {
                if (element == null) { return defValue; }
                //根据路径获取节点
                string strTemp = element.GetAttribute(strNode);
                return Convert.ToDateTime(strTemp);
            }
            catch
            {
                return defValue;
            }
        }
        #endregion
        /// <summary>
        /// 获取XML文件的根元素
        /// </summary>
        public XmlNode GetXmlRoot()
        {
            return xmlDoc.DocumentElement;
        }
        #region 获取所有列表
        /// <summary>
        /// 获取所有列表
        /// </summary>
        /// <returns>如为1，表示获取成功，为0为失败</returns>
        public XmlNodeList GetList()
        {
            try
            {
                return xmlDoc.DocumentElement.SelectNodes("child::list");
            }
            catch
            {
                return null;
            }
        }
        #endregion
        #region 获取所有列表
        /// <summary>
        /// 获取所有列表
        /// </summary>
        /// <returns>如为1，表示获取成功，为0为失败</returns>
        public XmlNodeList GetList(string xpath)
        {
            try
            {
                return xmlDoc.DocumentElement.SelectNodes(xpath);
            }
            catch
            {
                return null;
            }
        }
        #endregion
        #region 新增节点
        /// <summary>
        /// 新增节点
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public int AddNode(string strName, string strValue)
        {
            try
            {
                XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root");
                XmlNode childXmlNode = xmlDoc.CreateElement("list");
                xmlNode2.AppendChild(childXmlNode);
                XmlElement element2 = (XmlElement)childXmlNode;
                element2.SetAttribute(strName, strValue);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 新增节点并定位到新节点
        /// <summary>
        /// 新增节点并定位到新节点
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="strValue"></param>
        /// <returns></returns>
        public int AddNode2(string strName, string strValue)
        {
            try
            {
                XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root");
                xmlNode = xmlDoc.CreateElement("list");
                xmlNode2.AppendChild(xmlNode);
                element = (XmlElement)xmlNode;
                element.SetAttribute(strName, strValue);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 新增设置节点并定位
        /// <summary>
        /// 新增设置节点并定位
        /// </summary>
        /// <returns></returns>
        public int AddNodeBySet()
        {
            return AddNode2("id", "Setting");
        }
        #endregion
        #region 新增节点并定位到新节点
        /// <summary>
        /// 在指定节点前新增节点并定位到新节点
        /// </summary>
        /// <param name="strName"></param>
        /// <param name="strValue"></param>
        /// <param name="xn"></param>
        /// <returns></returns>
        public int AddNodeBefore(string strName, string strValue, XmlNode xn)
        {
            try
            {
                XmlNode xmlNode2 = xmlDoc.SelectSingleNode("root");
                xmlNode = xmlDoc.CreateElement("list");
                xmlNode2.InsertBefore(xmlNode, xn);
                element = (XmlElement)xmlNode;
                element.SetAttribute(strName, strValue);
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        /// <summary>
        /// 获取当前节点
        /// </summary>
        /// <returns></returns>
        public XmlNode GetNowXMLNode()
        {
            return xmlNode;
        }
        #region 删除节点
        /// <summary>
        /// 删除节点
        /// </summary>
        /// <returns></returns>
        public int DeleteNode()
        {
            try
            {
                //element.RemoveAll();
                GetXmlRoot().RemoveChild(xmlNode);
                xmlNode = null;
                element = null;
                return 1;
            }
            catch
            {
                return 0;
            }
        }
        #endregion
        #region 获取XML文本
        /// <summary>
        /// 获取XML文本
        /// </summary>
        /// <returns></returns>
        public string GetXMLText()
        {
            return xmlDoc.OuterXml;
        }
        /// <summary>
        /// 获取XML文本
        /// </summary>
        /// <returns></returns>
        public string XMLText
        {
            get { return xmlDoc.OuterXml; }
        }
        #endregion
        #region 获取XML文本
        /// <summary>
        /// 获取文本
        /// </summary>
        /// <returns></returns>
        public string GetText()
        {
            return xmlDoc.ToString(); ;
        }
        /// <summary>
        /// 获取文本
        /// </summary>
        /// <returns></returns>
        public string Text
        {
           get { return xmlDoc.ToString(); }
        }
        #endregion
    }
}
