一 前言
先來了解下操作XML所涉及到的幾個類及之間的關係 如果大家發現少寫了一些常用的方法,麻煩在評論中指出,我一定會補上的!謝謝大家
* 1 XMLElement 主要是針對節點的一些屬性進行操作
* 2 XMLDocument 主要是針對節點的CUID操作
* 3 XMLNode 為抽象類,做為以上兩類的基類,提供一些操作節點的方法
清楚了以上的關係在操作XML時會更清晰一點
二 具體操作(C#)
以下會對Xml的結點與屬性做增 刪 改 查的操作也滿足了實際工作中的大部分情況
先構造一棵XML樹如下,其中也涉及到了寫入xml文件的操作
1 public void CreatXmlTree(string xmlPath) 2 { 3 XElement xElement = new XElement( 4 new XElement("BookStore", 5 new XElement("Book", 6 new XElement("Name", "C#入門", new XAttribute("BookName", "C#")), 7 new XElement("Author", "Martin", new XAttribute("Name", "Martin")), 8 new XElement("Adress", "上海"), 9 new XElement("Date", DateTime.Now.ToString("yyyy-MM-dd")) 10 ), 11 new XElement("Book", 12 new XElement("Name", "WCF入門", new XAttribute("BookName", "WCF")), 13 new XElement("Author", "Mary", new XAttribute("Name", "Mary")), 14 new XElement("Adress", "北京"), 15 new XElement("Date", DateTime.Now.ToString("yyyy-MM-dd")) 16 ) 17 ) 18 ); 19 20 //需要指定編碼格式,否則在讀取時會拋:根級別上的資料無效。 第 1 行 位置 1異常 21 XmlWriterSettings settings = new XmlWriterSettings(); 22 settings.Encoding = new UTF8Encoding(false); 23 settings.Indent = true; 24 XmlWriter xw = XmlWriter.Create(xmlPath,settings); 25 xElement.Save(xw); 26 //寫入檔案 27 xw.Flush(); 28 xw.Close(); 29 }
然後得到如下的XML樹
1 <?xml version="1.0" encoding="utf-8"?> 2 <BookStore> 3 <Book> 4 <Name BookName="C#">C#入門</Name> 5 <Author Name="Martin">Martin</Author> 6 <Date>2013-10-11</Date> 7 <Adress>上海</Adress> 8 <Date>2013-10-11</Date> 9 </Book> 10 <Book> 11 <Name BookName="WCF">WCF入門</Name> 12 <Author Name="Mary">Mary</Author> 13 <Adress>北京</Adress> 14 <Date>2013-10-11</Date> 15 </Book> 16 </BookStore>
以下操作都是對生成的XML樹進行操作
2.1 新增節點與屬性
新增節點NewBook並增加屬性Name="WPF"
1 public void Create(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 6 var root = xmlDoc.DocumentElement;//取到根結點 7 XmlNode newNode = xmlDoc.CreateNode("element", "NewBook", ""); 8 newNode.InnerText = "WPF"; 9 10 //新增為根元素的第一層子結點 11 root.AppendChild(newNode); 12 xmlDoc.Save(xmlPath); 13 }
開篇有寫操作xml節點屬性主要用XmlElement物件所以取到結點後要轉型別
1 //屬性 2 public void CreateAttribute(string xmlPath) 3 { 4 XmlDocument xmlDoc = new XmlDocument(); 5 xmlDoc.Load(xmlPath); 6 var root = xmlDoc.DocumentElement;//取到根結點 7 XmlElement node = (XmlElement)xmlDoc.SelectSingleNode("BookStore/NewBook"); 8 node.SetAttribute("Name", "WPF"); 9 xmlDoc.Save(xmlPath); 10 11 }
效果如下
2.2 刪除節點與屬性
1 public void Delete(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 var root = xmlDoc.DocumentElement;//取到根結點 6 7 var element = xmlDoc.SelectSingleNode("BookStore/NewBook"); 8 root.RemoveChild(element); 9 xmlDoc.Save(xmlPath); 10 }
刪除屬性
1 public void DeleteAttribute(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 XmlElement node = (XmlElement)xmlDoc.SelectSingleNode("BookStore/NewBook"); 6 //移除指定屬性 7 node.RemoveAttribute("Name"); 8 //移除當前節點所有屬性,不包括預設屬性 9 //node.RemoveAllAttributes(); 10 xmlDoc.Save(xmlPath); 11 }
2.3 修改節點與屬性
xml的節點預設是不允許修改的,本文也就不做處理了
修改屬性程式碼如下
1 public void ModifyAttribute(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 XmlElement element = (XmlElement)xmlDoc.SelectSingleNode("BookStore/NewBook"); 6 element.SetAttribute("Name", "Zhang"); 7 xmlDoc.Save(xmlPath); 8 }
效果如下
2.4 獲取節點與屬性
1 public void Select(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 //取根結點 6 var root = xmlDoc.DocumentElement;//取到根結點 7 //取指定的單個結點 8 XmlNode oldChild = xmlDoc.SelectSingleNode("BookStore/NewBook"); 9 10 //取指定的結點的集合 11 XmlNodeList nodes = xmlDoc.SelectNodes("BookStore/NewBook"); 12 13 //取到所有的xml結點 14 XmlNodeList nodelist = xmlDoc.GetElementsByTagName("*"); 15 }
屬性
1 public void SelectAttribute(string xmlPath) 2 { 3 XmlDocument xmlDoc = new XmlDocument(); 4 xmlDoc.Load(xmlPath); 5 XmlElement element = (XmlElement)xmlDoc.SelectSingleNode("BookStore/NewBook"); 6 string name = element.GetAttribute("Name"); 7 Console.WriteLine(name); 8 }
三 具體操作 (linq to XML)
Linq to Xml 也沒什麼變化只操作物件改變了主要涉及的幾個物件如下 注:我並沒有用linq的語法去操作元素。
XDocument:用於建立一個XML例項文件
XElement:用於一些節點與節點屬性的基本操作
以下是對Xml的 一些簡單的操作
3.1 新增節點與屬性
1 public void Create(string xmlPath) 2 { 3 XDocument xDoc = XDocument.Load(xmlPath); 4 XElement xElement = xDoc.Element("BookStore"); 5 xElement.Add(new XElement("Test", new XAttribute("Name", "Zery"))); 6 xDoc.Save(xmlPath); 7 }
屬性
1 public void CreateAttribute(string xmlPath) 2 { 3 XDocument xDoc = XDocument.Load(xmlPath); 4 IEnumerable<XElement> xElement = xDoc.Element("BookStore").Elements("Book"); 5 foreach (var element in xElement) 6 { 7 element.SetAttributeValue("Name", "Zery"); 8 } 9 xDoc.Save(xmlPath); 10 }
3.2 刪除節點與屬性
1 public void Delete(string xmlPath) 2 { 3 XDocument xDoc = XDocument.Load(xmlPath); 4 XElement element = (XElement)xDoc.Element("BookStore").Element("Book"); 5 element.Remove(); 6 xDoc.Save(xmlPath); 7 }
屬性
1 public void DeleteAttribute(string xmlPath) 2 { 3 XDocument xDoc = XDocument.Load(xmlPath); 4 //不能跨級取節點 5 XElement element = xDoc.Element("BookStore").Element("Book").Element("Name"); 6 element.Attribute("BookName").Remove(); 7 xDoc.Save(xmlPath); 8 }
3.3 修改節點屬性
節點.net沒提供修改的方法本文也不做處理
修改屬性與新增實質是同一個方法
1 public void ModifyAttribute(string xmlPath) 2 { 3 XDocument xDoc = XDocument.Load(xmlPath); 4 XElement element = xDoc.Element("BookStore").Element("Book"); 5 element.SetAttributeValue("BookName","ZeryTest"); 6 xDoc.Save(xmlPath); 7 }
四 總結
把文章寫完時,又掃去了自己的一個盲區,雖然都是些簡單的操作,但在實際的開中,又何嘗不是由簡單到複雜呢。我覺得身為程式設計師就應該遇到自己的盲區時,立馬花時間去了解,不說要了解多深入,但至少基本的還是要知道,等到工作中真需時,只要稍微花點時間就可以了。
如果覺得文章對你有點幫助,不妨點下推薦,你的推薦讓我對寫文章能有更多的激情!
成長在於積累!
Demo 原始碼
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using System.Web; using System.Xml.Linq; namespace XMLOperation { class Program { static void Main(string[] args) { /*=============Linq 讀寫XML==================*/ string wxmlPath = @"F:\XmlTest\test.xml"; XmlWriteReadLinqOperation writeReadLinq = new XmlWriteReadLinqOperation(); // writeReadLinq.WriteXml(wxmlPath); writeReadLinq.CreatXmlTree(wxmlPath); //string xmlPath = @"F:\XML.xml"; string xmlPath = @"C:\Users\zery.zhang\Desktop\ProjectDemo\XML.xml"; /* * 1 三者之間的關係用圖畫出 * 2 XMLElement 主要是針對節點的一些屬性進行操作 * 3 XMLDocument 主要是針對節點的CUID操作 * 4 XMLNode 為抽象類,做為以上兩類的基類,提供一些操作節點的方法 */ //===========C# to Xml==========// XmlOperation xmlOperation = new XmlOperation(); //xmlOperation.Create(xmlPath); //xmlOperation.CreateAttribute(xmlPath); //xmlOperation.Delete(xmlPath); //xmlOperation.DeleteAttribute(xmlPath); //xmlOperation.Modify(xmlPath); //xmlOperation.ModifyAttribute(xmlPath); //xmlOperation.Select(xmlPath); //xmlOperation.SelectAttribute(xmlPath); /*=============Linq to Xml===========*/ XmlOperationToLinq xOperation = new XmlOperationToLinq(); // xOperation.Create(xmlPath); /* *1 給指定的XML節點的所有子節點增加一個節點,並增加屬性 *2 刪除指定節點的子節點的指定屬性 *3 */ string lxmlPath = @"F:\XmlTest\test.xml"; xOperation.Create(lxmlPath); xOperation.CreateAttribute(lxmlPath); //xperation.Delete(lxmlPath); //xOperation.DeleteAttribute(lxmlPath); // xOperation.ModifyAttribute(lxmlPath); /*=============C# 讀寫XML===============*/ XmlWriteReadOperation writeRead = new XmlWriteReadOperation(); Console.Read(); } } class XmlOperation { public void Create(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); var root = xmlDoc.DocumentElement;//取到根結點 XmlNode newNode = xmlDoc.CreateNode("element", "Name", ""); newNode.InnerText = "Zery"; //新增為根元素的第一層子結點 root.AppendChild(newNode); xmlDoc.Save(xmlPath); } //屬性 public void CreateAttribute(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); XmlElement node = (XmlElement)xmlDoc.SelectSingleNode("Collection/Book"); node.SetAttribute("Name", "C#"); xmlDoc.Save(xmlPath); } public void Delete(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); var root = xmlDoc.DocumentElement;//取到根結點 var element = xmlDoc.SelectSingleNode("Collection/Name"); root.RemoveChild(element); xmlDoc.Save(xmlPath); } public void DeleteAttribute(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); XmlElement node = (XmlElement)xmlDoc.SelectSingleNode("Collection/Book"); //移除指定屬性 node.RemoveAttribute("Name"); //移除當前節點所有屬性,不包括預設屬性 node.RemoveAllAttributes(); xmlDoc.Save(xmlPath); } public void Modify(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); var root = xmlDoc.DocumentElement;//取到根結點 XmlNodeList nodeList = xmlDoc.SelectNodes("/Collection/Book"); //xml不能直接更改結點名稱,只能複製然後替換,再刪除原來的結點 foreach (XmlNode node in nodeList) { var xmlNode = (XmlElement)node; xmlNode.SetAttribute("ISBN", "Zery"); } xmlDoc.Save(xmlPath); } public void ModifyAttribute(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); XmlElement element = (XmlElement)xmlDoc.SelectSingleNode("Collection/Book"); element.SetAttribute("Name", "Zhang"); xmlDoc.Save(xmlPath); } public void Select(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); //取根結點 var root = xmlDoc.DocumentElement;//取到根結點 //取指定的單個結點 XmlNode singleNode = xmlDoc.SelectSingleNode("Collection/Book"); //取指定的結點的集合 XmlNodeList nodes = xmlDoc.SelectNodes("Collection/Book"); //取到所有的xml結點 XmlNodeList nodelist = xmlDoc.GetElementsByTagName("*"); } public void SelectAttribute(string xmlPath) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlPath); XmlElement element = (XmlElement)xmlDoc.SelectSingleNode("Collection/Book"); string name = element.GetAttribute("Name"); } } class XmlOperationToLinq { //其它操作 public void OtherOperaton() { //加檔案頭 } public void Create(string xmlPath) { XDocument xDoc = XDocument.Load(xmlPath); XElement xElement = xDoc.Element("BookStore"); xElement.Add(new XElement("Test", new XAttribute("Name", "Zery"))); xDoc.Save(xmlPath); } public void CreateAttribute(string xmlPath) { XDocument xDoc = XDocument.Load(xmlPath); IEnumerable<XElement> xElement = xDoc.Element("BookStore").Elements("Book"); foreach (var element in xElement) { element.SetAttributeValue("Name", "Zery"); } xDoc.Save(xmlPath); } public void Delete(string xmlPath) { XDocument xDoc = XDocument.Load(xmlPath); XElement element = (XElement)xDoc.Element("BookStore").Element("Book"); element.Remove(); xDoc.Save(xmlPath); } public void DeleteAttribute(string xmlPath) { XDocument xDoc = XDocument.Load(xmlPath); //不能跨級取節點 XElement element = xDoc.Element("BookStore").Element("Book").Element("Name"); element.Attribute("BookName").Remove(); xDoc.Save(xmlPath); } public void ModifyAttribute(string xmlPath) { XDocument xDoc = XDocument.Load(xmlPath); XElement element = xDoc.Element("BookStore").Element("Book"); element.SetAttributeValue("BookName","ZeryTest"); xDoc.Save(xmlPath); } } internal class XmlWriteReadOperation { } class XmlWriteReadLinqOperation { public void CreatXmlTree(string xmlPath) { XElement xElement = new XElement( new XElement("BookStore", new XElement("Book", new XElement("Name", "C#入門", new XAttribute("BookName", "C#")), new XElement("Author", "Martin", new XAttribute("Name", "Martin")), new XElement("Adress", "上海"), new XElement("Date", DateTime.Now.ToString("yyyy-MM-dd")) ), new XElement("Book", new XElement("Name", "WCF入門", new XAttribute("BookName", "WCF")), new XElement("Author", "Mary", new XAttribute("Name", "Mary")), new XElement("Adress", "北京"), new XElement("Date", DateTime.Now.ToString("yyyy-MM-dd")) ) ) ); //需要指定編碼格式,否則在讀取時會拋:根級別上的資料無效。 第 1 行 位置 1異常 XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = new UTF8Encoding(false); settings.Indent = true; XmlWriter xw = XmlWriter.Create(xmlPath,settings); xElement.Save(xw); //寫入檔案 xw.Flush(); xw.Close(); } public void WriteXml(string xmlPath) { XElement xElement = new XElement( new XElement("Store", new XElement("Book", "技術類", new XElement("Name", "C#入門", new XAttribute("BookName", "C#")), new XElement("Author", "Martin", new XAttribute("Name", "Zery")), new XComment("以下為註釋"),//xml註釋 new XElement("Date", DateTime.Now.ToString(), new XAttribute("PublicDate", DateTime.Now.ToString())) )) ); XmlWriter xw = XmlWriter.Create(xmlPath); //儲存到XmlWriter xElement.Save(xw); //寫入檔案 xw.Flush(); xw.Close(); } } }