关于XML文件的读写,上一个项目是将数据写入到XML文件中,然后每次写入,都会单独创建一个文件,容易造成文件的臃肿,而且也不太安全。
本项目将数据写入到一个XML文件中,然后读取XML文件,判断是否有对应节点,读取对应数据。
知识点
1、获取项目运行路径
csharp
//获取模块的完整路径。
string path1 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
//获取和设置当前目录(该进程从中启动的目录)的完全限定目录
string path2 = System.Environment.CurrentDirectory;
//获取应用程序的当前工作目录
string path3 = System.IO.Directory.GetCurrentDirectory();
//获取程序的基目录
string path4 = System.AppDomain.CurrentDomain.BaseDirectory;
//获取和设置包括该应用程序的目录的名称
string path5 = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
//获取启动了应用程序的可执行文件的路径
string path6 = System.Windows.Forms.Application.StartupPath;
//获取启动了应用程序的可执行文件的路径及文件名
string path7 = System.Windows.Forms.Application.ExecutablePath;
Console.WriteLine($"--path1--{path1}");
//结果显示:--path1--C:\Users\Rush\Desktop\C#\获取当前路径\bin\Debug\获取当前路径.exe
Console.WriteLine($"--path2--{path2}");
//结果显示:--path2--C:\Users\Rush\Desktop\C#\获取当前路径\bin\Debug
Console.WriteLine($"--path3--{path3}");
//结果显示:--path3--C: \Users\Rush\Desktop\C#\获取当前路径\bin\Debug
Console.WriteLine($"--path4--{path4}");
//结果显示:--path4--C: \Users\Rush\Desktop\C#\获取当前路径\bin\Debug\
Console.WriteLine($"--path5--{path5}");
//结果显示:--path5--C:\Users\Rush\Desktop\C#\获取当前路径\bin\Debug\
Console.WriteLine($"--path6--{path6}");
//结果显示:--path6--C: \Users\Rush\Desktop\C#\获取当前路径\bin\Debug
Console.WriteLine($"--path7--{path7}");
//结果显示:--path7--C:\Users\Rush\Desktop\C#/获取当前路径/bin/Debug/获取当前路径.exe
string resultString = Regex.Match(path3, @".*(?=bin\\Debug)").Value;
Console.WriteLine(resultString);
//结果显示:C: \Users\Rush\Desktop\C#\获取当前路径\
2、notepad++中实现代码整体缩进和退格
缩进 :Tab键
退格 :Shift + Tab键
写入数据
实现逻辑:
1、判断配方数据XML文件是否存在,如果存在,则加载XML文件,并读取根目录。读取配方参数数值,将数值绑定一级和二级节点,最后将一级二级节点绑定根目录。保存文件
2、如果配方数据XML文件不存在,直接创建根目录,并读取配方参数数值,创建一级、二级节点,最后将创建的一二级节点绑定根目录。保存文件
csharp
private void button1_Click(object sender, EventArgs e)
{
//判断xml文件是否存在
string fileNamePath = Environment.CurrentDirectory.ToString();
string FruitNameRD, MilkWeightRD, SugarWeightRD;
string RecipeName;
//string FilePath = @"D:\码云\C#\程序案例\GLBDB\RecipeDB.xml";
//string FilePath = Environment.CurrentDirectory.ToString()+"RecipeDB.xml";
string FilePath = Path.Combine(Environment.CurrentDirectory.ToString(), "RecipeDB.xml");
if (comboBox1.SelectedIndex == null)
{
comboBox1.SelectedIndex = 0;
}
FruitNameRD = comboBox1.SelectedItem.ToString();
MilkWeightRD = textBox1.Text.Trim();
SugarWeightRD = textBox2.Text.Trim();
RecipeName = textBox3.Text.Trim();
if (File.Exists(FilePath))
{
//配方xml文件存在,则对XML文件进行读写
//加载XML文件
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(FilePath);
XmlElement RecipeDB = xmlDoc.DocumentElement;
//将配方名称添加到根目录下
XmlElement RecipeDb = xmlDoc.CreateElement("配方名称");
RecipeDb.InnerText = RecipeName;
//添加二级节点:牛奶参数
XmlElement RecipeDb01Para01 = xmlDoc.CreateElement("牛奶");
RecipeDb01Para01.InnerText = MilkWeightRD;
RecipeDb.AppendChild(RecipeDb01Para01);
//添加二级节点:糖参数
XmlElement RecipeDb01Para02 = xmlDoc.CreateElement("糖");
RecipeDb01Para02.InnerText = SugarWeightRD;
RecipeDb.AppendChild(RecipeDb01Para02);
//创建二级节点:水果参数
XmlElement RecipeDb01Para03 = xmlDoc.CreateElement("水果");
RecipeDb01Para03.InnerText = FruitNameRD;
RecipeDb.AppendChild(RecipeDb01Para03);
RecipeDB.AppendChild(RecipeDb);
xmlDoc.Save(FilePath);
}
else
{
//创建XML对象
XmlDocument xmlDoc = new XmlDocument();
//创建声明(可选)
XmlDeclaration dec = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
xmlDoc.AppendChild(dec);
//创建根节点
XmlElement RecipeDB = xmlDoc.CreateElement("奶茶配方");
xmlDoc.AppendChild(RecipeDB);
//添加一级节点:奶茶配方
XmlElement RecipeDb01 = xmlDoc.CreateElement("配方名称");
RecipeDb01.InnerText = RecipeName;
RecipeDB.AppendChild(RecipeDb01);
//添加二级节点:牛奶参数
XmlElement RecipeDb01Para01 = xmlDoc.CreateElement("牛奶");
RecipeDb01Para01.InnerText = MilkWeightRD;
RecipeDb01.AppendChild(RecipeDb01Para01);
//添加二级节点:糖参数
XmlElement RecipeDb01Para02 = xmlDoc.CreateElement("糖");
RecipeDb01Para02.InnerText = SugarWeightRD;
RecipeDb01.AppendChild(RecipeDb01Para02);
//创建二级节点:水果参数
XmlElement RecipeDb01Para03 = xmlDoc.CreateElement("水果");
RecipeDb01Para03.InnerText = FruitNameRD;
RecipeDb01.AppendChild(RecipeDb01Para03);
// xmlDoc.Save(fileNamePath + "ReceipeData.xml");
xmlDoc.Save(FilePath);
}
label5.Text = "配方"+ RecipeName+"已创建完成";
}
读取数据
根据配方名称,查询XML文件,如果XML文件中有对应配方名称,则读取下面的二级节点数据,如果没有,则提示没有。
csharp
XDocument doc = XDocument.Load(FilePath);
string targetname = textBox4.Text.Trim();
var RecipeDbWR = from RecipeDBWR in doc.Descendants("配方名称")
//let recipeName = GetDirectText(RecipeDBWR).Trim() // 获取纯配方名称
//where recipeName == targetname
let recipeName = string.Concat(RecipeDBWR.Nodes().OfType<XText>().Select(textnode => textnode.Value)).Trim()
where recipeName == targetname
select new
{
MilkWeightWR = RecipeDBWR.Element("牛奶")?.Value ?? "",
TeaWeightWR = RecipeDBWR.Element("糖")?.Value ?? "",
FruitNameWR = RecipeDBWR.Element("水果")?.Value ?? ""
};
// 获取第一个匹配的配方(无匹配则为null)
var matchedRecipe = RecipeDbWR.FirstOrDefault();
// 处理查询结果
if (matchedRecipe == null)
{
label6.Text = "未找到该奶茶配方";
// 清空输入框
textBox6.Text = textBox5.Text = textBox7.Text = "";
}
else
{
textBox6.Text = matchedRecipe.MilkWeightWR.ToString();
textBox5.Text = matchedRecipe.TeaWeightWR.ToString();
textBox7.Text = matchedRecipe.FruitNameWR.ToString();
label6.Text = "配方查询完毕";
}
上述代码的关键是获取节点内的纯文本内容(过滤掉子元素)