上一篇中讲到XML基本的结构,还有增删改查的方法,这一篇中我们就来利用XML来完成一个简单的订单系统,主要是实现一个简单学生名单的增删改查,如果想要应用到实际的环境中建议考虑数据量的问题,如果数据量大使用XML的话会比较耗时,使用SQL的性能会好一些

 

这里使用WinForm窗体程序,大致界面如下:

 

  1. 创建了两个窗体,一个主窗体用来显示名单数据,当添加或者编辑操作时则使用另外一个窗体。
  2. 主窗体中放置四个按钮,以及一个DataGridView控件,另外一个添加、编辑窗体,则按照相应的字段放置好控件。
  3. 给各控件命好名。

XML文档的格式如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <学生名单>
 4 
 5   <学生 Name="李四一" class="0102">
 6 
 7     <性别></性别>
 8 
 9     <生日>1999年1月2日</生日>
10 
11     <学号>20170</学号>
12 
13   </学生>
14 
15   <学生 Name="张三三" class="高一">
16 
17     <性别></性别>
18 
19     <学号>0102</学号>
20 
21     <生日>2017年6月18日</生日>
22 
23   </学生>
24 
25 </学生名单>

 学生名单为根元素,班级为根元素中的子元素,班级中又嵌套<学生>标记,了解了数据是以怎么的结构储存那么下面就继续。

 

数据在DataGridView中的显示
将XML中的数据,顺序显示在DataGridView控件中
 

 1 //创建一个datatable存储XML中的数据
 2 
 3 DataTable dt = new DataTable();
 4 
 5 //指定每一列的列名,和数据类型
 6 
 7 dt.Columns.Add("Id", (typeof(System.String)));
 8 
 9 dt.Columns.Add("班级", (typeof(System.String)));
10 
11 dt.Columns.Add("姓名", (typeof(System.String)));
12 
13 dt.Columns.Add("学号", (typeof(System.String)));
14 
15 dt.Columns.Add("生日", (typeof(System.String)));
16 
17 dt.Columns.Add("性别", (typeof(System.String)));
18 
19 //创建一个DataRow对象
20 
21 DataRow dr = dt.NewRow();
22 
23  
24 
25 XmlDocument doc = new XmlDocument();
26 
27 //为相对路径表示前二级的目录
28 
29 doc.Load(@"..//..//Students.xml");
30 
31 XmlElement root = doc.DocumentElement;
32 
33 XmlNodeList studentNodes = root.GetElementsByTagName("学生");
34 
35 //使用foreach遍历集合元素
36 
37 foreach(var item in studentNodes)
38 
39 {
40 
41     dr["Id"] = ((XmlElement)item).GetAttribute("Id");
42 
43     dr["班级"] = ((XmlElement)item).GetAttribute("Class");
44 
45     dr["姓名"] = ((XmlElement)item).GetAttribute("Name");
46 
47     dr["学号"] = ((XmlElement)item).GetElementsByTagName("学号")[0].InnerText;
48 
49     dr["生日"] = ((XmlElement)item).GetElementsByTagName("生日")[0].InnerText;
50 
51     dr["性别"] = ((XmlElement)item).GetElementsByTagName("性别")[0].InnerText;
52 
53     dt.Rows.Add(dr);
54 
55 }
56 
57 //将DataTable绑定到DataGridView控件
58 
59 dgvStudents.DataSource = dt;

 

增加记录

因为添加学生和编辑学生都需要在同一个窗体,那么在打开添加或编辑窗体时使用构造函数来传值,并判断是编辑还是添加。 

  1 添加编辑窗体代码:
  2 
  3 public partial class FrmStudentAddandEdit : Form
  4 
  5 {
  6 
  7 //全局变量接受传值
  8 
  9 bool IsAdd;
 10 
 11 string Name;
 12 
 13     //使用构造函数进行传值 true为增加,false为编辑
 14 
 15     public FrmStudentAddandEdit(bool isAdd, string name)
 16 
 17 {
 18 
 19 this.IsAdd = isAdd;
 20 
 21 this.Name = name;
 22 
 23         InitializeComponent();
 24 
 25     }
 26 
 27 }
 28 
 29  
 30 
 31 主窗体添加按钮单击事件代码:
 32 
 33 private void btnAdd_Click(object sender, EventArgs e)
 34 
 35 {
 36 
 37 //在创建窗体时传值
 38 
 39      FrmStudentAddandEdit form = new FrmStudentAddandEdit(true);
 40 
 41      form.ShowDialog();
 42 
 43 }
 44 
 45  
 46 
 47 新增记录代码:
 48 
 49 private void btnOK_Click(object sender, EventArgs e)
 50 
 51 {
 52 
 53     XmlDocument doc = new XmlDocument();
 54 
 55     doc.Load(@"..//..//Students.xml");
 56 
 57     XmlElement root = doc.DocumentElement;
 58 
 59     //添加<学生>子节点
 60 
 61     XmlElement Shutdent = doc.CreateElement("学生");
 62 
 63     //设置Name属性和Class属性
 64 
 65     Shutdent.SetAttribute("Name", txtName.Text.Trim());
 66 
 67     Shutdent.SetAttribute("Class", txtClass.Text.Trim());
 68 
 69     //创建子节点
 70 
 71     XmlElement eSex = doc.CreateElement("性别");
 72 
 73     XmlText tSex = doc.CreateTextNode(cmbSex.Text.Trim());
 74 
 75     //子节点添加内容
 76 
 77     eSex.AppendChild(tSex);
 78 
 79     //将子节点添加进学生标记
 80 
 81     Shutdent.AppendChild(eSex);
 82 
 83  
 84 
 85     XmlElement eNum = doc.CreateElement("学号");
 86 
 87     XmlText tNum = doc.CreateTextNode(txtNumber.Text.Trim());
 88 
 89     eNum.AppendChild(tNum);
 90 
 91     Shutdent.AppendChild(eNum);
 92 
 93  
 94 
 95     XmlElement eBirthday = doc.CreateElement("生日");
 96 
 97     XmlText tBirthday = doc.CreateTextNode(dtpBirthday.Text.Trim('-'));
 98 
 99     eBirthday.AppendChild(tBirthday);
100 
101     Shutdent.AppendChild(eBirthday);
102 
103  
104 
105     //将<学生>标记添加进根节点
106 
107     root.AppendChild(Shutdent);
108 
109  
110 
111     doc.Save(@"..//..//Students.xml");
112 
113 MessageBox.Show("添加成功!");
114 
115 this.Close();
116 
117 }
View Code

 

编辑记录

由于编辑需要查找到这条记录然后复制到控件中显示,那么在我们启动”添加或编辑窗体”时需要判断当前是添加状态还是编辑状态,并将表格选择行的姓名字段传给构造函数,通过这个姓名字段查找相应的值,然后筛选出来再给控件赋值。 

  1 主窗口编辑按钮单击事件:
  2 
  3 private void btnEdit_Click(object sender, EventArgs e)
  4 
  5 {
  6 
  7 //获取当前选择表格的行索引
  8 
  9    int dgvIndex = dgvStudents.CurrentRow.Index;
 10 
 11    //根据行索引获取单元格的值
 12 
 13    string name = dgvStudents.Rows[dgvIndex].Cells["姓名"].Value.ToString();
 14 
 15    FrmStudentAddandEdit form = new FrmStudentAddandEdit(false,name);
 16 
 17    form.ShowDialog();
 18 
 19 }
 20 
 21  
 22 
 23 窗体启动事件进行判断是添加还是编辑:
 24 
 25 private void FrmStudentAddandEdit_Load(object sender, EventArgs e)
 26 
 27 {
 28 
 29    if (IsAdd)
 30 
 31    {
 32 
 33       this.Text = "添加学生";
 34 
 35    }
 36 
 37    else
 38 
 39    {
 40 
 41       this.Text = "编辑学生名单";
 42 
 43       XmlDocument doc = new XmlDocument();
 44 
 45       doc.Load(@"..//..//Students.xml");
 46 
 47       XmlElement root = doc.DocumentElement;
 48 
 49       //筛选出符合条件的标记
 50 
 51       XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
 52 
 53       //筛选出符合条件并给控件赋值
 54 
 55       txtName.Text = selectEle.GetAttribute("Name");
 56 
 57       txtClass.Text = selectEle.GetAttribute("Class");
 58 
 59       txtNumber.Text = selectEle.GetElementsByTagName("学号")[0].InnerText;
 60 
 61       dtpBirthday.Text = selectEle.GetElementsByTagName("生日")[0].InnerText;
 62 
 63       cmbSex.Text = selectEle.GetElementsByTagName("性别")[0].InnerText;
 64 
 65      }
 66 
 67 }
 68 
 69 同样在编辑好内容后,单击确定按钮后判断当前是添加状态还是编辑状态:
 70 
 71 private void btnOK_Click(object sender, EventArgs e)
 72 
 73 {
 74 
 75    if (IsAdd)
 76 
 77    {
 78 
 79        //添加记录代码….
 80 
 81    }
 82 
 83    else
 84 
 85    {
 86 
 87        this.Text = "编辑学生名单";
 88 
 89        XmlDocument doc = new XmlDocument();
 90 
 91        doc.Load(@"..//..//Students.xml");
 92 
 93        XmlElement root = doc.DocumentElement;
 94 
 95        //筛选出符合条件的标记
 96 
 97        XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
 98 
 99        selectEle.SetAttribute("Name",txtName.Text.Trim());
100 
101        selectEle.SetAttribute("Class",txtClass.Text.Trim());
102 
103        //筛选出的对象赋给XMLElement对象
104 
105        XmlElement eSex = (XmlElement)selectEle.GetElementsByTagName("性别")[0];
106 
107        eSex.InnerText = cmbSex.Text;
108 
109        XmlElement eNumber = (XmlElement)selectEle.GetElementsByTagName("学号")[0];
110 
111        eNumber.InnerText = txtNumber.Text;
112 
113        XmlElement eBirth = (XmlElement)selectEle.GetElementsByTagName("生日")[0];
114 
115        eBirth.InnerText = dtpBirthday.Text;
116 
117  
118 
119        doc.Save(@"..//..//Students.xml");
120 
121        MessageBox.Show("修改成功!");
122 
123        //这一步很重要一定要关闭窗口不然再次修改会出现不可预料的BUG
124 
125        this.Close();
126 
127    }
128 
129 }
View Code

 

删除记录

  也是一样的逻辑获取当前选择表格的姓名字段,然后按照相关姓名进行删除,如果姓名不是唯一字段,那么可以使用ID,每次添加一条记录的时候最大ID+1

 1 //获取当前选择表格的行索引及姓名
 2 
 3 int dgvIndex = dgvStudents.CurrentRow.Index;
 4 
 5 string name = dgvStudents.Rows[dgvIndex].Cells["姓名"].Value.ToString();
 6 
 7 //筛选出符合条件的标记
 8 
 9 XmlElement selectEle = (XmlElement)root.SelectSingleNode("/学生名单/学生[@Name='" + Name + "']");
10 
11 //删除指定子元素
12 
13 root.RemoveChild(selectEle);
14 
15 doc.Save(“…”);
16 
17 //具体代码省略。。。。。不会的同学可以回到上篇文章。

 

上面介绍的操作方法是最常使用几种的,可以使用XML来完成一个数据量比较小的软件,或者可以用来做软件的配置文件。