xpath表达式
xpath表达式语法文章
//xpath表达式
XmlDocument xmlDocObj = new XmlDocument();
xmlDocObj.Load("file:///C:/Users/lenovo/Documents/visual%20studio%202015/Projects/11Net%E5%9F%BA%E7%A1%80%E5%8A%A0%E5%BC%BA%E5%8D%81%E4%B8%80%E5%A4%A9-%E5%A7%94%E6%89%98%20%E4%BA%8B%E4%BB%B6%20%E5%8F%8D%E5%B0%84/13Net%E5%9F%BA%E7%A1%80%E5%8A%A0%E5%BC%BA%E5%8D%81%E4%B8%89%E5%A4%A9-XML%E6%B7%B1%E5%85%A5/bin/Debug/listPersonXML.xml");
//xpath表达式不需要去记忆,用的时候去查就ok
//"//person"表示所有的person元素
XmlNodeList nodeList1 = xmlDocObj.SelectNodes("//person");
foreach (XmlNode node in nodeList1)
{
MessageBox.Show(node.Name + "," + node.InnerText);
}
//"//person[@pID='003']"表示所有pID属性为003的person元素
XmlNodeList nodeList2 = xmlDocObj.SelectNodes("//person[@pID='003']");
foreach (XmlNode node in nodeList2)
{
MessageBox.Show(node.InnerText);
}
使用xpath表达式对xml文件增删改查
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using static System.Windows.Forms.ListViewItem;
namespace _14Net基础加强十四天_xpath_深拷贝问题
{
public partial class xml增删改查和登录 : Form
{
public xml增删改查和登录()
{
InitializeComponent();
}
private void xml增删改查和登录_Load(object sender, EventArgs e)
{
//调用加载xml的方法
LoadXMLToListView();
}
//将加载xml到listview中封装成一个方法
private void LoadXMLToListView()
{
//清空listview
listView1.Items.Clear();
//加载xml到listview
XmlDocument xmlDocObj = new XmlDocument();
xmlDocObj.Load("file:///C:/Users/lenovo/Documents/visual%20studio%202015/Projects/11Net%E5%9F%BA%E7%A1%80%E5%8A%A0%E5%BC%BA%E5%8D%81%E4%B8%80%E5%A4%A9-%E5%A7%94%E6%89%98%20%E4%BA%8B%E4%BB%B6%20%E5%8F%8D%E5%B0%84/14Net%E5%9F%BA%E7%A1%80%E5%8A%A0%E5%BC%BA%E5%8D%81%E5%9B%9B%E5%A4%A9-xpath%20%E6%B7%B1%E6%8B%B7%E8%B4%9D%E9%97%AE%E9%A2%98/users.xml");
//获取所有的user标签
XmlNodeList userNodeList = xmlDocObj.SelectNodes("/users/user");
foreach (XmlNode userNode in userNodeList)
{
ListViewItem listViewItem = listView1.Items.Add(userNode.Attributes["id"].Value);
listViewItem.SubItems.Add(userNode.SelectSingleNode("name").InnerText.Trim());
listViewItem.SubItems.Add(userNode.SelectSingleNode("password").InnerText.Trim());
}
}
//增加用户
private void button1_Click(object sender, EventArgs e)
{
//获取用户输入的用户id,用户名,密码
string id = txtID.Text.Trim();
string userName = txtUserName.Text.Trim();
string pwd = txtPwd.Text.Trim();
//加载xml文档
XmlDocument xmlDocObj = new XmlDocument();
xmlDocObj.Load(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
if (xmlDocObj.SelectNodes("/users/user[@id=" + id + "]").Count > 0)
{
MessageBox.Show("该用户id已存在!");
}
else
{
//创建user标签元素
XmlElement userEle = xmlDocObj.CreateElement("user");
userEle.SetAttribute("id", id);
//创建name标签元素
XmlElement nameEle = xmlDocObj.CreateElement("name");
nameEle.InnerText = userName;
userEle.AppendChild(nameEle);
//创建password标签元素
XmlElement pwdEle = xmlDocObj.CreateElement("password");
pwdEle.InnerText = pwd;
userEle.AppendChild(pwdEle);
//将user添加到文档中
xmlDocObj.DocumentElement.AppendChild(userEle);
//写入xml
xmlDocObj.Save(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//重新将xml加载到listview中
LoadXMLToListView();
}
}
//listview双击事件
private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
//确保有选中项
if (listView1.SelectedItems.Count > 0)
{
ListViewSubItemCollection subItemCollection = listView1.SelectedItems[0].SubItems;
txtEditID.Text = subItemCollection[0].Text.Trim();
txtEditUserName.Text = subItemCollection[1].Text.Trim();
txtEditPwd.Text = subItemCollection[2].Text.Trim();
}
}
//修改用户信息
private void button2_Click(object sender, EventArgs e)
{
//获取想要修改的用户id,用户名,密码
string id = txtEditID.Text.Trim();
string userName = txtEditUserName.Text.Trim();
string pwd = txtEditPwd.Text.Trim();
//加载xml
XmlDocument xmlDocObj = new XmlDocument();
xmlDocObj.Load(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//根据id得到对应的user标签元素
XmlNode userNode = xmlDocObj.SelectSingleNode("/users/user[@id=" + id + "]");
//修改name和password标签的内容
userNode.SelectSingleNode("name").InnerText = userName;
userNode.SelectSingleNode("password").InnerText = pwd;
//重新写入xml
xmlDocObj.Save(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//重新将xml加载到listview中
LoadXMLToListView();
}
//删除,使用XDocument方式
private void button4_Click(object sender, EventArgs e)
{
//确保有选中项
if (listView1.SelectedItems.Count > 0)
{
//加载xml
XDocument xDocObj = XDocument.Load(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//获取选中项中的id
string id = listView1.SelectedItems[0].Text;
IEnumerable<XElement> ie = xDocObj.Descendants("user").Where((element) =>
{
if (element.Attribute("id").Value == id)
{
return true;
}
else
{
return false;
}
});
foreach (XElement ele in ie)
{
//将自己移除
ele.Remove();
break;
}
//xml重新保存
xDocObj.Save(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//重新加载xml
LoadXMLToListView();
}
}
private void button3_Click(object sender, EventArgs e)
{
//获取登录时的用户名和密码
string userName = txtLoginName.Text.Trim();
string pwd = txtLoginPwd.Text.Trim();
//加载xml文档
XmlDocument xmlDocObj = new XmlDocument();
xmlDocObj.Load(@"C:\Users\lenovo\documents\visual studio 2015\Projects\11Net基础加强十一天-委托 事件 反射\14Net基础加强十四天-xpath 深拷贝问题\users.xml");
//通过用户名去查找name标签
XmlNode nameNode = xmlDocObj.SelectSingleNode("//name[.='" + userName + "']");
if (nameNode != null)
{
//根据当前name标签元素获取它后面的password标签元素
XmlNode pwdNode = nameNode.NextSibling;
if (userName == nameNode.InnerText && pwd == pwdNode.InnerText)
{
MessageBox.Show("登陆成功!");
return;
}
}
MessageBox.Show("登录失败!");
}
}
}
关于string类型的值能够赋值给XName类型对象的问题
string类和XName类之间没有任何关系,为什么string类型的值却能够赋值给XName类型的对象,原因在于XName这个类的内部实现了一个特殊的方法:
//
// 摘要:
// 将已格式化为展开的 XML 名称(即 {namespace}localname)的字符串转换为 System.Xml.Linq.XName 对象。
//
// 参数:
// expandedName:
// 一个字符串,其中包含 {namespace}localname 格式的展开的 XML 名称。
//
// 返回结果:
// 从展开名称构造的 System.Xml.Linq.XName 对象。
[CLSCompliant(false)]
public static implicit operator XName(string expandedName);
xml序列化
//声明一个list集合(Dcitionary集合无法序列化为xml)
List<Person> personList = new List<Person>();
personList.Add(new Person() { Name = "张三", Age = 20, Gender = '男' });
personList.Add(new Person() { Name = "李四", Age = 21, Gender = '男' });
personList.Add(new Person() { Name = "王五", Age = 22, Gender = '男' });
//声明一个xml序列化器
XmlSerializer xmlSeralizer = new XmlSerializer(typeof(List<Person>));
//创建一个写入流
using (FileStream fsWrite = new FileStream("seralizer.xml", FileMode.Create, FileAccess.Write))
{
//执行序列化的方法
xmlSeralizer.Serialize(fsWrite, personList);
}
自定义一个将普通对象序列化为xml的方法
private void MyXMLSeralize(object obj, Type type)
{
//先判断传进来的是普通对象还是list集合
if (type == typeof(List<Person>))
{
//执行集合的序列化方法
}
else
{
XDocument xDocObj = new XDocument();
//设置xml文档声明
XDeclaration dec = new XDeclaration("1.0", "utf-8", "no");
xDocObj.Declaration = dec;
//执行普通对象的序列化方法
Type typeObj = typeof(Person);
//添加根节点
XElement rootEle = new XElement(typeObj.Name);
xDocObj.Add(rootEle);
//通过反射得到所有属性
PropertyInfo[] props = typeObj.GetProperties();
foreach (PropertyInfo prop in props)
{
rootEle.SetElementValue(prop.Name, prop.GetValue(obj));
}
//保存xml
xDocObj.Save(typeObj.Name + ".xml");
}
}
浅拷贝和深拷贝
1.浅拷贝和深拷贝的区别:浅拷贝就是引用同一个对象,深拷贝就是重新创建了一个对象
2.深拷贝和浅拷贝的作用:假如一个对象的数据需要共享,那么使用浅拷贝就可以,如果想要复制一个对象,并且两个对象的数据操作不能互相干扰,则需要深拷贝。
实现深拷贝(一般是实现ICloneable接口在Clone()方法中写深拷贝)
实现深拷贝的思路:先进行二进制序列化,然后再反序列化,将反序列化的对象返回就得到了深拷贝的对象。
//定义一个深拷贝的方法
public Person ShenClone()
{
//定义一个内存流
using (MemoryStream ms = new MemoryStream())
{
//创建一个二进制序列化器
BinaryFormatter bf = new BinaryFormatter();
//先序列化
bf.Serialize(ms, this);
ms.Position = 0;
//再反序列化
return bf.Deserialize(ms) as Person;
}
}