一、简介XML
XML 是可扩展标记语言(Extensible Markup Language)的缩写,WinForm里面的app.config以及Web程序中的web.config文件都属于XML文件。
较为入门详细介绍:http://www.ibm.com/developerworks/cn/xml/x-newxml/
二、通过XmlDocument操作Xml文档
XmlDocument方法详见MSDN:https://msdn.microsoft.com/zh-cn/library/d5awd922
首先添加命名空间:using System.Xml;
定义公有对象:private XmlDocument xmlDoc = null;
本文示例以数据库连接设置为例,为方便建立如下数据库信息类DataBaseInfo,包含数据库服务器名、数据库名、用户名以及密码:
1 public class DataBaseInfo 2 { 3 public DataBaseInfo() 4 { } 5 6 /// <summary> 7 /// 数据库服务器地址名 8 /// </summary> 9 private string ip; 10 public string IP 11 { 12 get { return ip; } 13 set { ip = value; } 14 } 15 16 /// <summary> 17 /// 数据库名 18 /// </summary> 19 private string database; 20 public string DataBase 21 { 22 get { return database; } 23 set { database = value; } 24 } 25 26 /// <summary> 27 /// 用户名 28 /// </summary> 29 private string userID; 30 public string UserID 31 { 32 get { return userID; } 33 set { userID = value; } 34 } 35 36 /// <summary> 37 /// 密码 38 /// </summary> 39 private string password; 40 public string PassWord 41 { 42 get { return password; } 43 set { password = value; } 44 } 45 46 }
1、创建新的空Xml文件
1 /// <summary> 2 /// 新建空的Xml文件 3 /// </summary> 4 /// <param name="XmlFilePath">文件路径名</param> 5 public void CreateXml(string XmlFilePath) 6 { 7 xmlDoc = new XmlDocument(); 8 //加入XML的声明段落,<?xml version="1.0" encoding="utf-8"?> 9 XmlDeclaration xmldecl; 10 xmldecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null); 11 xmlDoc.AppendChild(xmldecl); 12 13 //加入根节点Connections 14 XmlElement root = xmlDoc.CreateElement("", "Connections", ""); 15 xmlDoc.AppendChild(root); 16 }
在指定路径下得到Xml文件:
<?xml version="1.0" encoding="utf-8"?> <Connections />
2、保存与打开
1 /// <summary> 2 /// 保存Xml文件 3 /// </summary> 4 /// <param name="XmlFilePath">保存路径名</param> 5 public void SaveXml(string XmlFilePath) 6 { 7 xmlDoc.Save(XmlFilePath); 8 } 9 10 /// <summary> 11 /// 打开已存在的Xml文档 12 /// </summary> 13 /// <param name="XmlFilePath">Xml文档路径名</param> 14 public void OpenXml(string XmlFilePath) 15 { 16 xmlDoc = new XmlDocument(); 17 xmlDoc.Load(XmlFilePath); 18 }
3、增加指定节点名的数据库连接参数信息
1 /// <summary> 2 /// 增加节点信息 3 /// </summary> 4 /// <param name="nodeTag">根节点名</param> 5 /// <param name="db">数据库信息</param> 6 public void AddXmlInfo(string nodeTag, DataBaseInfo db) 7 { 8 XmlNode root = xmlDoc.SelectSingleNode("Connections"); //通过SelectSingleNode方法查找<Connections> 9 XmlElement node1 = xmlDoc.CreateElement(nodeTag); //创建一个<Node>节点 10 11 XmlElement node2 = xmlDoc.CreateElement("IP"); 12 node2.InnerText = db.IP; //设置文本节点 13 node1.AppendChild(node2); //添加到<Node>节点中 14 15 node2 = xmlDoc.CreateElement("DataBase"); 16 node2.InnerText = db.DataBase; 17 node1.AppendChild(node2); 18 19 node2 = xmlDoc.CreateElement("User"); 20 node2.InnerText = db.UserID; 21 node1.AppendChild(node2); 22 23 node2 = xmlDoc.CreateElement("PassWord"); 24 node2.InnerText = db.PassWord; 25 node1.AppendChild(node2); 26 27 root.AppendChild(node1);//添加到<Conncetions>节点中 28 }
运用示例:
1 public Form1() 2 { 3 InitializeComponent(); 4 } 5 6 XmlTool xmltool = new XmlTool(); 7 string XmlFilePath = Application.StartupPath + "\\test.xml"; 8 DataBaseInfo DB = new DataBaseInfo(); 9 10 private void button1_Click(object sender, EventArgs e) 11 { 12 DB.IP = textBox1.Text.Trim(); 13 DB.DataBase = textBox2.Text.Trim(); 14 DB.UserID = textBox3.Text.Trim(); 15 DB.PassWord = textBox4.Text.Trim(); 16 17 if (!File.Exists(XmlFilePath)) 18 { 19 xmltool.CreateXml(XmlFilePath); 20 xmltool.AddXmlInfo("Server1", DB); 21 xmltool.SaveXml(XmlFilePath); 22 } 23 else 24 { 25 xmltool.OpenXml(XmlFilePath); 26 xmltool.AddXmlInfo("Server2", DB); 27 xmltool.SaveXml(XmlFilePath); 28 } 29 }
添加信息后的Xml文件:
<?xml version="1.0" encoding="utf-8"?> <Connections> <Server1> <IP>111.1.1.1</IP> <DataBase>Test1</DataBase> <User>111</User> <PassWord>aaa</PassWord> </Server1> <Server2> <IP>222.2.2.2</IP> <DataBase>Test2</DataBase> <User>222</User> <PassWord>bbb</PassWord> </Server2> <Server2> <IP>333.3.3.3</IP> <DataBase>Test3</DataBase> <User>333</User> <PassWord>ccc</PassWord> </Server2>
</Connections>
4、获取所有节点信息
1 /// <summary> 2 /// 获得所有子节点信息 3 /// </summary> 4 /// <returns></returns> 5 public List<DataBaseInfo> GetXmlInfo() 6 { 7 // 得到根节点Connections 8 XmlNode root = xmlDoc.SelectSingleNode("Connections"); 9 10 List<DataBaseInfo> DataBaseList = new List<DataBaseInfo>(); //存放结果 11 12 if (root.HasChildNodes)//如果有子节点 13 { 14 XmlNodeList node = root.ChildNodes; // 得到根节点的所有子节点 15 16 foreach (XmlNode xn in node) 17 { 18 DataBaseInfo DataBase = new DataBaseInfo(); 19 // 将节点转换为元素,便于得到节点的属性值 20 XmlElement xe = (XmlElement)xn; 21 // 得到Book节点的所有子节点 22 XmlNodeList childnodes = xe.ChildNodes; 23 DataBase.IP = childnodes.Item(0).InnerText; 24 DataBase.DataBase = childnodes.Item(1).InnerText; 25 DataBase.UserID = childnodes.Item(2).InnerText; 26 DataBase.PassWord = childnodes.Item(3).InnerText; 27 DataBaseList.Add(DataBase); 28 } 29 } 30 else 31 { } 32 return DataBaseList; 33 }
运用示例:
1 private void button2_Click(object sender, EventArgs e) 2 { 3 List<DataBaseInfo> DataBaseList = new List<DataBaseInfo>(); //存放结果 4 if (File.Exists(XmlFilePath)) 5 { 6 xmltool.OpenXml(XmlFilePath); 7 DataBaseList = xmltool.GetXmlInfo(); 8 for (int i = 0; i < DataBaseList.Count; i++) 9 { 10 dataGridView1.RowCount = DataBaseList.Count; 11 dataGridView1[0, i].Value = DataBaseList[i].IP; 12 dataGridView1[1, i].Value = DataBaseList[i].DataBase; 13 dataGridView1[2, i].Value = DataBaseList[i].UserID; 14 dataGridView1[3, i].Value = DataBaseList[i].PassWord; 15 } 16 } 17 else 18 { 19 MessageBox.Show("路径下Xml文件不存在!"); 20 } 21 }
5、获得指定节点的信息
1 /// <summary> 2 /// 读取xml中的指定节点的值,如果有多个同名节点,则全部读取 3 /// </summary> 4 /// <param name="nodeTag"></param> 5 /// <returns></returns> 6 public List<DataBaseInfo> ReadXmlNodes(string nodeTag) 7 { 8 List<DataBaseInfo> DataBaseList = new List<DataBaseInfo>(); //存放结果 9 try 10 { 11 XmlNodeList xnList = xmlDoc.SelectNodes("//" + nodeTag); 12 13 foreach (XmlNode xn in xnList) 14 { 15 DataBaseInfo DataBase = new DataBaseInfo(); 16 DataBase.IP = (xn.SelectSingleNode("IP")).InnerText; 17 DataBase.DataBase = (xn.SelectSingleNode("DataBase")).InnerText; 18 DataBase.UserID = (xn.SelectSingleNode("User")).InnerText; 19 DataBase.PassWord = (xn.SelectSingleNode("PassWord")).InnerText; 20 DataBaseList.Add(DataBase); 21 } 22 } 23 catch(Exception e) 24 { 25 MessageBox.Show(e.Message); 26 } 27 return DataBaseList; 28 }
运用示例(取出所有节点为Server2的数据库参数信息):
1 private void button4_Click(object sender, EventArgs e) 2 { 3 List<DataBaseInfo> DataBaseList = new List<DataBaseInfo>(); //存放结果 4 if (File.Exists(XmlFilePath)) 5 { 6 xmltool.OpenXml(XmlFilePath); 7 DataBaseList = xmltool.ReadXmlNodes("Server2"); 8 for (int i = 0; i < DataBaseList.Count; i++) 9 { 10 dataGridView1.RowCount = DataBaseList.Count; 11 dataGridView1[0, i].Value = DataBaseList[i].IP; 12 dataGridView1[1, i].Value = DataBaseList[i].DataBase; 13 dataGridView1[2, i].Value = DataBaseList[i].UserID; 14 dataGridView1[3, i].Value = DataBaseList[i].PassWord; 15 } 16 } 17 else 18 { 19 MessageBox.Show("路径下Xml文件不存在!"); 20 } 21 }
6、删除指定节点所有信息
1 /// <summary> 2 /// 删除指定节点信息 3 /// </summary> 4 /// <param name="nodeTag"></param> 5 public void DeleteXml(string nodeTag) 6 { 7 XmlNode root = xmlDoc.SelectSingleNode("Connections"); 8 if (root.HasChildNodes)//如果有子节点 9 { 10 XmlNodeList nodelist = root.ChildNodes; 11 for (int i = 0; i < nodelist.Count; ) 12 { 13 if (nodelist[i].Name == nodeTag) 14 { 15 nodelist[i].ParentNode.RemoveChild(nodelist[i]); 16 } 17 else 18 { i++; } 19 } 20 } 21 else 22 { } 23 24 }
运用示例(删除Sever1节点信息):
1 //删除 2 private void button3_Click(object sender, EventArgs e) 3 { 4 if (File.Exists(XmlFilePath)) 5 { 6 xmltool.OpenXml(XmlFilePath); 7 xmltool.DeleteXml("Server1"); 8 xmltool.SaveXml(XmlFilePath); 9 } 10 else 11 { 12 MessageBox.Show("路径下Xml文件不存在!"); 13 } 14 }
删除操作后的Xml文件:
<?xml version="1.0" encoding="utf-8"?> <Connections> <Server2> <IP>222.2.2.2</IP> <DataBase>Test2</DataBase> <User>222</User> <PassWord>bbb</PassWord> </Server2> <Server2> <IP>333.3.3.3</IP> <DataBase>Test3</DataBase> <User>333</User> <PassWord>ccc</PassWord> </Server2> </Connections>
最后,不管对Xml文件做了何种操作,记得一定要保存,不然做什么都白瞎。删除功能之前试过用foreach,但是foreach只能遍历,删除找到的第一个指定节点下的内容,之后会跳出遍历,后面即使有相同的节点也不操作,故用for循环删除。
p.s:有不足之处请指正,谢谢!