【C#】XML文件操作
微软官方XML文档介绍:https://docs.microsoft.com/zh-cn/dotnet/standard/data/xml/ (强烈推荐!!!一篇足矣)
一、XmlDocument类
参考资料:
1.visual studio documentation:XmlDocument Class
//继承关系
public class XmlDocument : System.Xml.XmlNode
XmlDocument类是XML文档的内存表示。它实现了W3CXML文档对象模型(DOM)的第1级核心和第2级核心
DOM代表文档对象模型document object model
可以使用XmlDocument类将XML加载到DOM中,然后以编程方式读取、修改和删除文档中的XML。
示例部分:
1.将XML加载到文档对象模型中
<?xml version="1.0" encoding="utf-8"?>
<books xmlns="http://www.contoso.com/books">
<book genre="novel" ISBN="1-861001-57-8" publicationdate="1823-01-28">
<title>Pride And Prejudice</title>
<price>24.95</price>
</book>
<book genre="novel" ISBN="1-861002-30-1" publicationdate="1985-01-01">
<title>The Handmaid's Tale</title>
<price>29.95</price>
</book>
<book genre="novel" ISBN="1-861001-45-3" publicationdate="1811-01-01">
<title>Sense and Sensibility</title>
<price>19.95</price>
</book>
</books>
*******************从文件中加载xml,如果文件不存在,则先创建再加载***************
1 XmlDocument doc = new XmlDocument(); 2 doc.PreserveWhitespace = true; 3 try { doc.Load("booksData.xml"); } 4 catch (System.IO.FileNotFoundException) 5 { 6 doc.LoadXml("<?xml version=\"1.0\"?> \n" + 7 "<books xmlns=\"http://www.contoso.com/books\"> \n" + 8 " <book genre=\"novel\" ISBN=\"1-861001-57-8\" publicationdate=\"1823-01-28\"> \n" + 9 " <title>Pride And Prejudice</title> \n" + 10 " <price>24.95</price> \n" + 11 " </book> \n" + 12 " <book genre=\"novel\" ISBN=\"1-861002-30-1\" publicationdate=\"1985-01-01\"> \n" + 13 " <title>The Handmaid's Tale</title> \n" + 14 " <price>29.95</price> \n" + 15 " </book> \n" + 16 "</books>"); 17 }
2.导航文档树Navigate the document tree
xml文档树结构基本介绍:
文档由节点(Node)组成。
每个节点的正上方都有一个父节点(Parent Node)。
唯一没有父节点的节点是文档根节点(root node),因为它是顶级节点。
大多数节点都可以有子节点(child node),子节点是它们下面的节点。
处于同一级别的节点是同级节点(siblings)。
*******************获取根节点,并输出整个文档内容****************
1 using System; 2 using System.IO; 3 using System.Xml; 4 5 public class Sample 6 { 7 public static void Main() 8 { 9 //Create the XmlDocument. 10 XmlDocument doc = new XmlDocument(); 11 doc.LoadXml("<?xml version='1.0' ?>" + 12 "<book genre='novel' ISBN='1-861001-57-5'>" + 13 "<title>Pride And Prejudice</title>" + 14 "</book>"); 15 16 //Display the document element. 17 Console.WriteLine(doc.DocumentElement.OuterXml); 18 } 19 }
*******************获取根节点的第一个子节点,并遍历该节点的子节点(如果有)**************
1 using System; 2 using System.IO; 3 using System.Xml; 4 5 public class Sample 6 { 7 8 public static void Main() { 9 10 XmlDocument doc = new XmlDocument(); 11 doc.LoadXml("<book ISBN='1-861001-57-5'>" + 12 "<title>Pride And Prejudice</title>" + 13 "<price>19.95</price>" + 14 "</book>"); 15 16 XmlNode root = doc.FirstChild; 17 18 //Display the contents of the child nodes. 19 if (root.HasChildNodes) 20 { 21 for (int i=0; i<root.ChildNodes.Count; i++) 22 { 23 Console.WriteLine(root.ChildNodes[i].InnerText); 24 } 25 } 26 } 27 }
*******************获取节点的父节点*****************
使用ParentNode属性
*******************获取节点最后一个子节点*****************
1 using System; 2 using System.IO; 3 using System.Xml; 4 5 public class Sample 6 { 7 8 public static void Main() 9 { 10 XmlDocument doc = new XmlDocument(); 11 doc.LoadXml("<book ISBN='1-861001-57-5'>" + 12 "<title>Pride And Prejudice</title>" + 13 "<price>19.95</price>" + 14 "</book>"); 15 16 XmlNode root = doc.FirstChild; 17 18 Console.WriteLine("Display the price element..."); 19 Console.WriteLine(root.LastChild.OuterXml); 20 } 21 }
******************在兄弟节点中向前导航 Navigate forward across siblings******************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Xml; 3 4 public class Sample { 5 6 public static void Main() 7 { 8 9 XmlDocument doc = new XmlDocument(); 10 doc.Load("books.xml"); 11 12 XmlNode currNode = doc.DocumentElement.FirstChild; 13 Console.WriteLine("First book..."); 14 Console.WriteLine(currNode.OuterXml); 15 16 XmlNode nextNode = currNode.NextSibling; 17 Console.WriteLine("\r\nSecond book..."); 18 Console.WriteLine(nextNode.OuterXml); 19 20 } 21 }
******************在兄弟节点中向后导航 Navigate backwards across siblings******************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Xml; 3 4 public class Sample { 5 6 public static void Main() 7 { 8 9 XmlDocument doc = new XmlDocument(); 10 doc.Load("books.xml"); 11 12 XmlNode lastNode = doc.DocumentElement.LastChild; 13 Console.WriteLine("Last book..."); 14 Console.WriteLine(lastNode.OuterXml); 15 16 XmlNode prevNode = lastNode.PreviousSibling; 17 Console.WriteLine("\r\nPrevious book..."); 18 Console.WriteLine(prevNode.OuterXml); 19 } 20 }
找到节点:查找一个或多个数据节点的最常用方法是使用XPath查询字符串
******************获取单个节点*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public XmlNode GetBook(string uniqueAttribute, XmlDocument doc) 2 { 3 XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 4 nsmgr.AddNamespace("bk", "http://www.contoso.com/books"); 5 string xPathString = "//bk:books/bk:book[@ISBN='" + uniqueAttribute + "']"; 6 XmlNode xmlNode = doc.DocumentElement.SelectSingleNode(xPathString, nsmgr); 7 return xmlNode; 8 }
******************获取单个节点的属性和子节点的值*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void GetBookInformation(ref string title, ref string ISBN, ref string publicationDate, 2 ref string price, ref string genre, XmlNode book) 3 { 4 XmlElement bookElement = (XmlElement)book; 5 6 // Get the attributes of a book. 7 XmlAttribute attr = bookElement.GetAttributeNode("ISBN"); 8 ISBN = attr.InnerXml; 9 10 attr = bookElement.GetAttributeNode("genre"); 11 genre = attr.InnerXml; 12 13 attr = bookElement.GetAttributeNode("publicationdate"); 14 publicationDate = attr.InnerXml; 15 16 // Get the values of child elements of a book. 17 title = bookElement["title"].InnerText; 18 price = bookElement["price"].InnerText; 19 }
******************获取节点集合*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //This example selects all books where the author's last name is Austen, 2 //and then changes the price of those books. 3 using System; 4 using System.IO; 5 using System.Xml; 6 7 public class Sample { 8 9 public static void Main() 10 { 11 12 XmlDocument doc = new XmlDocument(); 13 doc.Load("booksort.xml"); 14 15 XmlNodeList nodeList; 16 XmlNode root = doc.DocumentElement; 17 18 //SelectNodes方法的参数是一个XPath表达式 19 nodeList=root.SelectNodes("descendant::book[author/last-name='Austen']"); 20 21 //Change the price on the books. 22 foreach (XmlNode book in nodeList) 23 { 24 book.LastChild.InnerText="15.95"; 25 } 26 27 Console.WriteLine("Display the modified XML document...."); 28 doc.Save(Console.Out); 29 30 } 31 }
//使用节点名获取节点集合
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.IO; 3 using System.Xml; 4 5 public class Sample 6 { 7 public static void Main() 8 { 9 //Create the XmlDocument. 10 XmlDocument doc = new XmlDocument(); 11 doc.Load("books.xml"); 12 13 //Display all the book titles. 14 XmlNodeList elemList = doc.GetElementsByTagName("title"); 15 for (int i=0; i < elemList.Count; i++) 16 { 17 Console.WriteLine(elemList[i].InnerXml); 18 } 19 20 } 21 }
******************编辑节点*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //This example edits a book node and its attributes.编辑单个节点 2 public void editBook(string title, string ISBN, string publicationDate, 3 string genre, string price, XmlNode book, bool validateNode, bool generateSchema) 4 { 5 6 XmlElement bookElement = (XmlElement)book; 7 8 // Get the attributes of a book. 9 bookElement.SetAttribute("ISBN", ISBN); 10 bookElement.SetAttribute("genre", genre); 11 bookElement.SetAttribute("publicationdate", publicationDate); 12 13 // Get the values of child elements of a book. 14 bookElement["title"].InnerText = title; 15 bookElement["price"].InnerText = price; 16 17 if (validateNode) 18 { 19 validateXML(generateSchema, bookElement.OwnerDocument); 20 } 21 }
******************添加节点*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //要添加节点,请使用CreateElement方法或CreateNode方法; 2 //要添加一个数据节点,比如一本书,使用CreateElement方法。 3 //对于任何其他类型的节点,如注释、空白节点或CDATA节点,请使用CreateNode方法 4 5 //本例创建一个book节点,向该节点添加属性,然后将该节点添加到文档中 6 public XmlElement AddNewBook(string genre, string ISBN, string misc, 7 string title, string price, XmlDocument doc) 8 { 9 // Create a new book element. 10 XmlElement bookElement = doc.CreateElement("book", "http://www.contoso.com/books"); 11 12 // Create attributes for book and append them to the book element. 13 XmlAttribute attribute = doc.CreateAttribute("genre"); 14 attribute.Value = genre; 15 bookElement.Attributes.Append(attribute); 16 17 attribute = doc.CreateAttribute("ISBN"); 18 attribute.Value = ISBN; 19 bookElement.Attributes.Append(attribute); 20 21 attribute = doc.CreateAttribute("publicationdate"); 22 attribute.Value = misc; 23 bookElement.Attributes.Append(attribute); 24 25 // Create and append a child element for the title of the book. 26 XmlElement titleElement = doc.CreateElement("title"); 27 titleElement.InnerText = title; 28 bookElement.AppendChild(titleElement); 29 30 // Introduce a newline character so that XML is nicely formatted. 31 bookElement.InnerXml = 32 bookElement.InnerXml.Replace(titleElement.OuterXml, 33 "\n " + titleElement.OuterXml + " \n "); 34 35 // Create and append a child element for the price of the book. 36 XmlElement priceElement = doc.CreateElement("price"); 37 priceElement.InnerText= price; 38 bookElement.AppendChild(priceElement); 39 40 // Introduce a newline character so that XML is nicely formatted. 41 bookElement.InnerXml = 42 bookElement.InnerXml.Replace(priceElement.OuterXml, priceElement.OuterXml + " \n "); 43 44 return bookElement; 45 46 }
******************移除节点*****************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //移除节点使用RemoveChild方法 2 //This example removes a book from the document and any whitespace that appears just before the book node. 3 public void deleteBook(XmlNode book) 4 { 5 XmlNode prevNode = book.PreviousSibling; 6 7 book.OwnerDocument.DocumentElement.RemoveChild(book); 8 9 10 if (prevNode.NodeType == XmlNodeType.Whitespace || 11 prevNode.NodeType == XmlNodeType.SignificantWhitespace) 12 { 13 prevNode.OwnerDocument.DocumentElement.RemoveChild(prevNode); 14 } 15 }
******************节点位置*****************
可以使用InsertBefore和InsertAfter方法选择要在文档中显示节点的位置。
这个例子显示了两个辅助方法。其中一个向上移动列表中的一个节点。另一个向下移动一个节点。
这些方法可用于允许用户在图书列表中上下移动图书的应用程序。
当用户选择了一本书并按下向上或向下按钮时,您的代码可以调用这样的方法来定位相应的书节点在其他书节点之前或之后的位置
//************************************************************************************
//
// Summary: Move elements up in the XML.
// 节点上移
//
//************************************************************************************
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public void MoveElementUp(XmlNode book) 2 { 3 XmlNode previousNode = book.PreviousSibling; 4 while (previousNode != null && (previousNode.NodeType != XmlNodeType.Element)) 5 { 6 previousNode = previousNode.PreviousSibling; 7 } 8 if (previousNode != null) 9 { 10 XmlNode newLineNode = book.NextSibling; 11 book.OwnerDocument.DocumentElement.RemoveChild(book); 12 if (newLineNode.NodeType == XmlNodeType.Whitespace | 13 newLineNode.NodeType == XmlNodeType.SignificantWhitespace) 14 { 15 newLineNode.OwnerDocument.DocumentElement.RemoveChild(newLineNode); 16 } 17 InsertBookElement((XmlElement)book, Constants.positionAbove, 18 previousNode, false, false); 19 } 20 }
//************************************************************************************
//
// Summary: Move elements down in the XML.
// 节点下移
//
//************************************************************************************
1 public void MoveElementDown(XmlNode book) 2 { 3 // Walk backwards until we find an element - ignore text nodes 4 XmlNode NextNode = book.NextSibling; 5 while (NextNode != null && (NextNode.NodeType != XmlNodeType.Element)) 6 { 7 NextNode = NextNode.NextSibling; 8 } 9 if (NextNode != null) 10 { 11 XmlNode newLineNode = book.PreviousSibling; 12 book.OwnerDocument.DocumentElement.RemoveChild(book); 13 if (newLineNode.NodeType == XmlNodeType.Whitespace | 14 newLineNode.NodeType == XmlNodeType.SignificantWhitespace) 15 { 16 newLineNode.OwnerDocument.DocumentElement.RemoveChild(newLineNode); 17 } 18 19 InsertBookElement((XmlElement)book, Constants.positionBelow, 20 NextNode, false, false); 21 } 22 23 }