在JSON没流行起来的时候xml一直作为程序存储配置信息的主流介质;特别是小型数据表方面还是不错的选择,所以经常涉及到的操作无非也就是增删改查,这篇博客主要是对这些对比较常用的操作做了个简单的总结
文件加载
SelectNodes()、SelectSingleNode()节点获取大法
创建XML文档及设置元素值
XmlReader与XmlWriter
DataSet与XML数据
Linq to XML
XML序列化与反序列化
文件加载
- 通过路径加载XML
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(fileName);//文件路径或者URL地址 Console.WriteLine(xmlDoc.InnerXml); Console.WriteLine("==============有逼格的分割线================"); xmlDoc.Load("http://feed.cnblogs.com/blog/picked/rss");//博客园精华帖RSS Console.WriteLine(xmlDoc.InnerXml);
- 通过文件流加载
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(stream); Console.WriteLine(xmlDoc.InnerXml); }
Load()方法还重载了一些方法,并且还有别的方式可以加载XML文档,比如LoadXml()直接加载一段XML串
SelectNodes()、SelectSingleNode()节点获取大法
<?xml version="1.0" encoding="utf-8" ?> <Names> <Name> <FirstName>John</FirstName> <LastName>Smith</LastName> </Name> <Name> <FirstName>James</FirstName> <LastName>White</LastName> </Name> </Names>
XML文件
- 通过XPath表达式的SelectNodes(string xpath)方法获取节点列表;SelectSingleNode(string xpath)获取第一个匹配的节点
XmlNodeList xmlNodes = xmlDoc.SelectNodes("/Names/Name");//第一个斜杠必须是根节点 foreach (XmlNode item in xmlNodes) { Console.WriteLine(item.InnerXml); } Console.WriteLine("=================================="); XmlNode xmlNode = xmlDoc.SelectSingleNode("/Names/Name"); Console.WriteLine(xmlNode.InnerXml); Console.WriteLine(xmlNode["LastName"].InnerText);//获取子节点
- 设置节点特性值查找节点
<Root> <Item Id="1" Grade="1">张三</Item> <Item Id="2" Grade="1">李四</Item> <Item Id="3" Grade="2">王五</Item> <Item Id="4" Grade="3">赵六</Item> </Root>
XmlNodeList xmlNodes = xmlDoc.SelectNodes("/Root/Item[@Grade='1']");//XPath表达式获取设置要获取节点的特性值信息 foreach (XmlNode item in xmlNodes) { Console.WriteLine(item.InnerText); }
- 获取第N个节点
XmlNode xmlNode = xmlDoc.SelectSingleNode("/Root/Item[position()=3]");//获取第N个节点(根据XML节点的顺序) Console.WriteLine(xmlNode.InnerText); Console.WriteLine("=============================="); XmlNodeList xmlNodes = xmlDoc.SelectNodes("/Root/Item[position()<=3]");//获取从第一个到第N个的节点(根据XML节点的顺序 foreach (XmlNode item in xmlNodes) { Console.WriteLine(item.InnerText); } Console.WriteLine("=============================="); xmlNodes = xmlDoc.SelectNodes("/Root/Item[position() > 2]");//获取大于第N个的节点(根据XML节点的顺序) foreach (XmlNode item in xmlNodes) { Console.WriteLine(item.InnerText); }
创建XML文档及设置元素值
XmlDocument xmlDoc = new XmlDocument(); XmlNode rootNode = xmlDoc.CreateElement("Root");//创建一个节点 xmlDoc.AppendChild(rootNode); Console.WriteLine(xmlDoc.InnerXml); Console.WriteLine("==============有逼格的分割线================"); XmlNode node = xmlDoc.CreateElement("Item"); XmlAttribute attribute = xmlDoc.CreateAttribute("Id");//创建节点特性 attribute.Value = ";//设置特性值 node.Attributes.Append(attribute); node.InnerText = "张三"; rootNode.AppendChild(node); Console.WriteLine(xmlDoc.InnerXml); Console.WriteLine("==============有逼格的分割线================"); node = xmlDoc.CreateElement("Item"); attribute = xmlDoc.CreateAttribute("Id"); attribute.Value = "; node.Attributes.Append(attribute); node.InnerText = "李四"; rootNode.AppendChild(node); Console.WriteLine(xmlDoc.InnerXml); xmlDoc.Save(fileName);//保存到文件
XmlReader与XmlWriter
XmlReader操作XML比XmlDocument更快、内存消耗更少(可以写一个测试验证一下);但是它需要去手动判断元素的类型,操作起来比XmlDocument稍微蛋疼一些
using (XmlWriter xmlWriter = XmlWriter.Create(fileName)) { xmlWriter.WriteStartDocument();//开始写入xml文档 xmlWriter.WriteStartElement("users"); xmlWriter.WriteStartElement("user"); xmlWriter.WriteAttributeString("); xmlWriter.WriteString("张三"); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("user"); xmlWriter.WriteAttributeString("); xmlWriter.WriteString("李四"); xmlWriter.WriteEndDocument();//结束写入xml文档 } using (XmlReader xmlReader = XmlReader.Create(fileName)) { while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element)//元素的类型 { Console.WriteLine(xmlReader.Name);//元素名称 if (xmlReader.HasAttributes) { Console.WriteLine(xmlReader.GetAttribute("Id"));//元素名称 } Console.WriteLine(xmlReader.ReadOuterXml());//获取节点的所有子内容 } } }
DataSet与XML数据
通过XmlReader将数据读入到DataSet数据集中
using (XmlReader xmlReader = XmlReader.Create(fileName, new XmlReaderSettings())) { DataSet ds = new DataSet(); ds.ReadXml(xmlReader); DataTable dt = ds.Tables[]; ; i < dt.Rows.Count - ; i++) { object[] items = dt.Rows[i].ItemArray; Console.WriteLine(string.Join(" ", items)); } }
将数据表保存到XML文件也是比较常用的
DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("Id", Type.GetType("System.Int32"))); dt.Columns.Add(new DataColumn("Grade", Type.GetType("System.Int32"))); dt.Columns.Add(new DataColumn("Name", Type.GetType("System.String"))); DataRow dr = dt.NewRow(); dr[; dr[; dr["Name"] = "孙七"; dt.Rows.Add(dr); ds.Tables.Add(dt); ds.Tables[].TableName = "Student";//每张表为根节点下的第一个子节点 ds.WriteXml(fileName);
Linq to XML
通过linq操作XML上手快、操作方便
//查询 XDocument xdoc = XDocument.Load(fileName); var query = from item in xdoc.Descendants("Item") select new { Id = item.Attribute("Id").Value, Name = item.Value }; foreach (var item in query) { Console.WriteLine(item.Id + " " + item.Name); }
//添加 XDocument xdoc = XDocument.Load(fileName); XElement xele = new XElement("Item","吴十?");//创建节点 xele.SetAttributeValue();//设置节点特性值 xdoc.Element("Root").Add(xele); xdoc.Save(fileName);
//删除 XDocument xdoc = XDocument.Load(fileName); XElement xele = xdoc.Descendants(")).FirstOrDefault(); xele.Remove(); xdoc.Save(fileName);
//修改 XDocument xdoc = XDocument.Load(fileName); XElement xele = xdoc.Descendants(")).FirstOrDefault(); xele.Value = "流年"; xdoc.Save(fileName);
XML序列化与反序列化
//序列化 , Grade = , Name = "王五" }; XmlSerializer serializer = new XmlSerializer(typeof(Student)); serializer.Serialize(Console.Out, student);
//反序列化 string input = "<?xml version=\"1.0\" encoding=\"gb2312\"?><student><Id> 1 </Id><Grade> 2 </Grade><Name> 李四 </Name></student>"; using (StringReader sr = new StringReader(input)) { XmlSerializer serializer = new XmlSerializer(typeof(Student)); Student student = (Student)serializer.Deserialize(sr); Console.WriteLine(student.Name); }
扩展阅读
http://www.dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples
http://www.tutorialspoint.com/linq/linq_xml.htm
https://msdn.microsoft.com/en-us/library/mt693062.aspx
http://broadcast.oreilly.com/2010/10/understanding-c-simple-linq-to.html
http://www.codeproject.com/Articles/24376/LINQ-to-XML
http://csharp.net-tutorials.com/xml/reading-xml-with-the-xmlreader-class/
https://msdn.microsoft.com/zh-cn/library/58a18dwa(v=vs.120).aspx
http://csharp.net-informations.com/xml/xml-de-serialization.htm