C#操作xml的3种方式
C#操作Xml有很多种方式,这里写出个人常使用的三种方式
XmlDocumentDataSetlinq to xml
首先声明本次操作使用的xml文件:books.xml;内容如下
<?xml version="1.0" encoding="UTF-8"?> <books> <book display="书本记录"> <name>哈里波特</name> <price>10</price> <memo>这是一本很好看的书。</memo> </book> <book id="B02"> <name>三国演义</name> <price>10</price> <memo>四大名著之一。</memo> </book> <book id="B03"> <name>水浒</name> <price>6</price> <memo>四大名著之一。</memo> </book> <book id="B04"> <name>红楼</name> <price>5</price> <memo>四大名著之一。</memo> </book> </books>
以下代码只适用于测试学习,不适用于工程代码
1. XmlDocument【传统方式】
直接上代码,暂时不做效率等对比
/// <summary> /// XmlDocument增删改查 /// </summary> public static void XmlDocumentOP() { XmlElement theBook = null, theElem = null, root = null; XmlDocument xmldoc = new XmlDocument(); try { xmldoc.Load("Books.xml"); root = xmldoc.DocumentElement; //--- 新建一本书开始 ---- theBook = xmldoc.CreateElement("book"); theElem = xmldoc.CreateElement("name"); theElem.InnerText = "新书"; theBook.AppendChild(theElem); theElem = xmldoc.CreateElement("price"); theElem.InnerText = "20"; theBook.AppendChild(theElem); theElem = xmldoc.CreateElement("memo"); theElem.InnerText = "新书更好看。"; theBook.AppendChild(theElem); root.AppendChild(theBook); Console.Out.WriteLine("--- 新建一本书开始 ----"); Console.Out.WriteLine(root.OuterXml); //--- 新建一本书完成 ---- //--- 下面对《哈里波特》做一些修改。 ---- //--- 查询找《哈里波特》---- theBook = (XmlElement)root.SelectSingleNode("/books/book[name='哈里波特']"); Console.Out.WriteLine("--- 查找《哈里波特》 ----"); Console.Out.WriteLine(theBook.OuterXml); //--- 此时修改这本书的价格 ----- theBook.GetElementsByTagName("price").Item(0).InnerText = "15";//getElementsByTagName返回的是NodeList,所以要跟上item(0)。另外,GetElementsByTagName("price")相当于SelectNodes(".//price")。 Console.Out.WriteLine("--- 此时修改这本书的价格 ----"); Console.Out.WriteLine(theBook.OuterXml); //--- 另外还想加一个属性id,值为B01 ---- theBook.SetAttribute("id", "B01"); Console.Out.WriteLine("--- 另外还想加一个属性id,值为B01 ----"); Console.Out.WriteLine(theBook.OuterXml); //--- 对《哈里波特》修改完成。 ---- //--- 再将所有价格低于10的书删除 ---- theBook = (XmlElement)root.SelectSingleNode("/books/book[@id='B02']"); Console.Out.WriteLine("--- 要用id属性删除《三国演义》这本书 ----"); Console.Out.WriteLine(theBook.OuterXml); theBook.ParentNode.RemoveChild(theBook); Console.Out.WriteLine("--- 删除后的XML ----"); Console.Out.WriteLine(xmldoc.OuterXml); //--- 再将所有价格低于10的书删除 ---- XmlNodeList someBooks = root.SelectNodes("/books/book[price<10]"); Console.Out.WriteLine("--- 再将所有价格低于10的书删除 ---"); Console.Out.WriteLine("--- 符合条件的书有 " + someBooks.Count + "本。 ---"); for (int i = 0; i < someBooks.Count; i++) { someBooks.Item(i).ParentNode.RemoveChild(someBooks.Item(i)); } Console.Out.WriteLine("--- 删除后的XML ----"); Console.Out.WriteLine(xmldoc.OuterXml); xmldoc.Save("books.xml");//保存到books.xml Console.In.Read(); } catch (Exception e) { Console.Out.WriteLine(e.Message); } }
以上代码来源于网络测试可行,作者忘记了
2. DataSet 操作xml【常用方式】
比较常用,方便快捷,类似操作数据库一样顺手
/// <summary> /// DataSet操作xml /// </summary> public static void XmlDataSetOP() { DataSet ds = new DataSet(); ds.ReadXml("books.xml"); /* <books> <book display="书本记录"> <name>哈里波特</name> <price>10</price> <memo>这是一本很好看的书。</memo> </book> <book id="B02"> <name>三国演义</name> <price>10</price> <memo>四大名著之一。</memo> </book> <book1 id="B04"> <name>红楼</name> <price>5</price> <memo>四大名著之一。</memo> </book1> </books> */ //ds 是多表集合,根节点没有实际意义,这样会生成两个数据表:book 和 book1 //book 表包含了子节点及属性所有节点的字段 //即 name price memo display id // 哈里波特 10 这是…书。 书本记录 B01 // 三国演义 10 四大…之一。 B02 //注意如果以上子节点含有属性,可能会建立关系表,如<name provice="english">哈里波特</name> 比较复杂 DataTable dt = ds.Tables["book"]; //查找数据 //1. 查询价格等于10的row记录 var row = dt.Select("price = 10"); //2. 查询价格等于10的记录 并且 name是 哈里波特的 var row1 = dt.Select("price = 10 and name = '哈里波特'"); //3.将DataTable 实现IEnumerable接口,AsEnumerable(),然后使用linq查询 var ss = from rowData in dt.AsEnumerable().Where(r => r["price"].ToString() == "10") where 1 == 1 select new { a = rowData["name"].ToString() }; //增加数据 dt.Rows.Add(new object[] { "aaa", 10, 11 });//注意这里请按照字段顺序编写,字段顺序:book子节点、book属性 //ds.GetXml();可直接输出当前最新xml,保存即可 //移除了这个条件下的记录 foreach (var item in dt.Select("price=10")) { dt.Rows.Remove(item); } //改, var cRow = dt.Select("name='水浒'"); if (cRow.Count() > 0) { cRow[0].BeginEdit(); cRow[0]["name"] = "水浒传"; cRow[0]["price"] = "20"; cRow[0].EndEdit(); } }
3. linq to Xml【比较人性化方式,据说效率最佳】
class Book { public string ID { get; set; } public string Display { get; set; } public string Name { get; set; } public string Price { get; set; } public string Memo { get; set; } private static XDocument doc = new XDocument(); public static string filePath = "books.xml"; public Book() { doc = XDocument.Load(filePath); } public Book(string filepath) { filePath = filepath; doc = XDocument.Load(filePath); } /// <summary> /// 增 /// </summary> /// <returns></returns> public bool Add() { XElement db = new XElement("book", new XAttribute("id", Guid.NewGuid().ToString()), new XAttribute("display", Display), new XElement("name", Name), new XElement("price", Price), new XElement("memo", Memo) ); try { //用XElement的Add方法 //XElement doc = XElement.Load(filePath); //doc.Add(db); //用XDocument的Add方法 doc.Element("books").Add(db); doc.Save(filePath); return true; } catch { return false; } } /// <summary> /// 删 /// </summary> /// <param name="id"></param> /// <returns></returns> public static bool RemoveData(string id) { XElement xe = (from db in doc.Element("books").Elements("book") where (db.Attribute("id") == null ? "" : db.Attribute("id").Value) == id select db).Single() as XElement; try { xe.Remove(); doc.Save(filePath); return true; } catch { return false; } } /// <summary> /// 改 /// </summary> /// <returns></returns> public bool Update() { XElement xe = (from db in doc.Element("books").Elements("book") where (db.Attribute("id") == null ? "" : db.Attribute("id").Value.ToString()) == ID select db).Single(); try { xe.Attribute("display").Value = Display; xe.Element("name").Value = Name; xe.Element("price").Value = Price; xe.Element("memo").Value = Memo; doc.Save(filePath); return true; } catch { return false; } } /// <summary> /// 查 /// </summary> /// <returns></returns> public List<Book> GetAll() { List<Book> dbs = (from db in doc.Element("books").Elements("book") select new Book { ID = db.Attribute("id") == null ? "" : db.Attribute("id").Value.ToString(), Display = db.Attribute("display") == null ? "" : db.Attribute("display").Value.ToString(), Name = db.Element("name") == null ? "" : db.Element("name").Value.ToString(), Price = db.Element("price") == null ? "" : db.Element("name").Value.ToString(), Memo = db.Element("memo") == null ? "" : db.Element("name").Value.ToString() }).ToList(); return dbs; } /// <summary> /// 查 /// </summary> /// <returns></returns> public List<Book> TakePage(out int totalSize, int index, int size) { List<Book> dbs = (from db in doc.Element("books").Elements("book") select new Book { ID = db.Attribute("id") == null ? "" : db.Attribute("id").Value.ToString(), Display = db.Attribute("display") == null ? "" : db.Attribute("display").Value.ToString(), Name = db.Element("name") == null ? "" : db.Element("name").Value.ToString(), Price = db.Element("price") == null ? "" : db.Element("name").Value.ToString(), Memo = db.Element("memo") == null ? "" : db.Element("name").Value.ToString() }).Skip((index - 1) * size).Take(size).ToList(); totalSize = GetAll().Count; return dbs; } /// <summary> /// 查 /// </summary> /// <returns></returns> public List<Book> GetSingleBook(string id) { List<Book> dbs = (from db in doc.Element("books").Elements("book") where (db.Attribute("id") == null ? "" : db.Attribute("id").Value.ToString()) == id select new Book { ID = db.Attribute("id") == null ? "" : db.Attribute("id").Value.ToString(), Display = db.Attribute("display") == null ? "" : db.Attribute("display").Value.ToString(), Name = db.Element("name") == null ? "" : db.Element("name").Value.ToString(), Price = db.Element("price") == null ? "" : db.Element("name").Value.ToString(), Memo = db.Element("memo") == null ? "" : db.Element("name").Value.ToString() }).ToList(); return dbs; } }