C#操作XML文档(XmlDocument、XmlNode、XmlAttribute、SelectSingleNode、SelectNodes、XmlNodeList)
XML文档是一种通用的文档,这种文档既可以用.config作为后缀也可以用.xml作为后缀。XML文档主要由元素节点和节点的属性共同构成的。它有且仅有一个根节点,其他的节点全部都是根节点的子节点或者子子节点;每一个节点有开始就一定会有结束,不可能出现有开始无结束的节点,节点主要有两种类型:有InnerText的<city>……</city>和没有InnerText的<city……/>。在节点中含有属性,一个节点可以含有多个属性,每个属性是由名字和值共同构成的。
在XML文档中,节点、属性都是区分大小写的。对于某个节点的属性,Name是不能重复的,即使在定义属性的时候,定义了两个name完全相同的属性,添加到同一个节点上面,后面的属性会把前面的属性覆盖,不会报语法错误;对于某个节点下面的子节点,则可以添加多个完全相同的子节点。
对XML文档的操作的前提是:XML文档已经存在,并且根节点已经存在。
一、添加节点和属性
1、定义一个XML的操作对象:
XmlDocument doc = new XmlDocument();
2、加载一个XML文件:
doc.Load(@"D:\App.config");
指定的文件一定要存在,否则会报错的。
3、获取根节点:
XmlNode root = doc.DocumentElement;
4、定义一个属性:
XmlAttribute ra = doc.CreateAttribute("Name");
5、给属性的值赋值:
ra.Value = "zwj2";
6、将属性添加到节点上面:
root.Attributes.Append(ra);
7、再定义一个节点为根节点的子节点:
XmlNode root1 = doc.CreateElement("table");
8、给节点赋文本值:
root1.InnerText = "sdf1";
9、给节点定义并添加属性
10、将该节点添加到父节点上去:
root.AppendChild(root1);
11、保存XML文档:
doc.Save(@"D:\App.config");
注意:可以对一个节点添加多个属性,那么各个属性会依次往后排;可以给根节点添加多个子节点,也可以对子节点再添加多个子节点。
二、查询和修改节点和属性
1、元素结点有Name属性,就是<>里面的串,也有InnerText属性(相当于文本结点),就是<></>之间的串:root.Name、root.InnerText。这些属性都是可以读写的。------------------------------XmlNode
2、属性结点有Name,也有Value:providerName="System.Data.SqlClient",前面为Name,后面为Value这些属性既可读也可写。-----------------------------------------------------------XmlAttribute
3、每一个结点有子结点的集合,也有属性的集合:root.ChildNodes、root.Attributes;集合都有count属性。
4、集合都满足索引:
对于属性集合,属性的name是不能重复的,所以索引可以是name字符串索引,那么name字符串要存在,否则返回的是一个null属性对象,不会报错;也可以是整数索引,那么此时的整数不能越界,否则是会报错的;:root.Attributes["name"]、root.Attributes[0],返回XmlAttribute。
对于子节点的集合,因为子节点可以完全相同,那么子节点的name肯定也可以相同,所以此时的索引只能是整数的,而不能是子节点name字符串,整数索引也不能越界,否则会报错: root.ChildNodes[10],返回XmlNode。
三、几个重要的函数
1、XmlNode XmlDocument.SelectSingleNode(@"configuration/twoNode/dayStart")
这个函数是用一个声明好的并且已经成功加载了某个配置文件的XmlDocument对象去调用SelectSingleNode函数;该函数的参数是配置文件中的从根节点名字开始一直往下最终到想要的节点的名字,整个名字路径都不能出错,注意是左斜杠;函数的返回值是第一次找到的XmlNode节点的对象,如果找不到就会返回null。
操作如下xml:
<?xmlversion="1.0"?>
<configuration>
<twoNode>
</twoNode>
<twoNode>
<dayStart>1</dayStart>
<dayStart>2</dayStart>
<dayStart>3</dayStart>
</twoNode>
</configuration>
如果执行该函数,那么将会找到节点:<dayStart>1</dayStart>
2、XmlNodeList XmlDocument.SelectNodes (@"configuration/twoNode/dayStart")
这个函数是用一个声明好的并且已经成功加载了某个配置文件的XmlDocument对象去调用SelectNodes函数;该函数的参数是配置文件中的从根节点名字开始一直往下最终到想要的节点的名字,整个名字路径都不能出错,注意是左斜杠;因为节点的名字是可能重复的,所以函数的返回值是找到的所有XmlNode节点对象的集合XmlNodeList,如果找不到就会返回null。
XmlNodeList是集合,那么就有count属性,可以直接对这个集合用[int index]来索引具体的对象,也可以用集合的Item(int index)函数来索引具体的对象,但是索引不能越界,否则会出错,返回的是XmlNode。
操作如下xml:
<?xmlversion="1.0"?>
<configuration>
<twoNode>
<dayStart>-1</dayStart>
<dayStart>-2</dayStart>
<dayStart>-3</dayStart>
</twoNode>
<twoNode>
<dayStart>1</dayStart>
<dayStart>2</dayStart>
<dayStart>3</dayStart>
</twoNode>
</configuration>
如果执行该函数,那么将会找到节点集合:
<dayStart>-1</dayStart>
<dayStart>-2</dayStart>
<dayStart>-3</dayStart>
<dayStart>1</dayStart>
<dayStart>2</dayStart>
<dayStart>3</dayStart>
操作如下xml:
<?xmlversion="1.0"?>
<configuration>
<twoNode>
</twoNode>
<twoNode>
<dayStart>1</dayStart>
<dayStart>2</dayStart>
<dayStart>3</dayStart>
</twoNode>
</configuration>
如果执行该函数,那么将会找到节点集合:
<dayStart>1</dayStart>
<dayStart>2</dayStart>
<dayStart>3</dayStart>
注:转载自csdn http://blog.csdn.net/zwj7612356/article/details/8183931
下面就开始进行实际操作吧!
一.添加一个xml文件,名为book.xml ,内容如下:
<?xml version="1.0" encoding="utf-8"?> <bookstore> <book Type="必修课" ISBN="7-111-19149-2"> <title>数据结构</title> <author>严蔚敏</author> <price>30.00</price> </book> <book Type="必修课" ISBN="7-111-19149-3"> <title>路由型与交换型互联网基础</title> <author>程庆梅</author> <price>27.00</price> </book> <book Type="必修课" ISBN="7-111-19149-4"> <title>计算机硬件技术基础</title> <author>李继灿</author> <price>25.00</price> </book> <book Type="必修课" ISBN="7-111-19149-5"> <title>软件质量保证与管理</title> <author>朱少民</author> <price>39.00</price> </book> <book Type="必修课" ISBN="7-111-19149-6"> <title>算法设计与分析</title> <author>王红梅</author> <price>23.00</price> </book> <book Type="选修课" ISBN="7-111-19149-1"> <title>计算机操作系统</title> <author>你猜</author> <price>28</price> </book> </bookstore>
二.添加一个web页面,名为 XML_Operation.aspx,页面内容如下:
一共4个按钮,分别是button1、button2、button3、button4,然后是一个GridView1用来显示数据
三.添加一个BookModel.cs类用于读取数据,内容如下:
public class BookModel { //构造函数 public BookModel(){} /// <summary> /// 所对应的课程类型 /// </summary> public string BookType { get; set; } /// <summary> /// 书所对应的ISBN号 /// </summary> public string BookISBN { get; set; } /// <summary> /// 书名 /// </summary> public string BookName { get; set; } /// <summary> /// 作者 /// </summary> public string BookAuthor { get; set; } /// <summary> /// 价格 /// </summary> public string BookPrice { get; set; } }
四.后台代码如下:
1.添加命名空间 using System.Xml;
2.添加公共方法,用于操作当前XML
1 /// <summary> 2 /// XML操作公共方法 3 /// </summary> 4 /// <param name="oname">操作类型,create代表创建、delete代表删除、update代表修改、select代表查询</param> 5 private void OperationXML(string oname) 6 { 7 8 XmlDocument xmldoc = new XmlDocument();//xml操作文档类 9 //xmldoc.Load(@"D:\Practice\Test20150703\AboutXML\AboutXML\book.xml"); 10 11 XmlReaderSettings set = new XmlReaderSettings(); 12 set.IgnoreComments = true;//忽略文档注释 13 XmlReader reader = XmlReader.Create(@"D:\Practice\Test20150703\AboutXML\AboutXML\book.xml", set); 14 xmldoc.Load(reader); 15 reader.Close(); 16 XmlNode node = xmldoc.SelectSingleNode("bookstore"); 17 XmlNodeList childs = node.ChildNodes; 18 switch (oname) 19 { 20 case "create"://增加 21 #region 22 XmlElement xmlnew = xmldoc.CreateElement("book"); 23 XmlAttribute xmlattri = xmldoc.CreateAttribute("Type");//添加类型 24 xmlattri.Value = "新类型"; 25 xmlnew.SetAttributeNode(xmlattri); 26 XmlAttribute isbnatti = xmldoc.CreateAttribute("ISBN");//添加编号 27 xmlnew.SetAttributeNode(isbnatti); 28 isbnatti.Value = DateTime.Now.ToString("yyyymmddHHmmssfff");//注意,最后的f代表毫秒,可以取毫秒的前几位数,比如毫秒123可以用ff取到12 29 node.AppendChild(xmlnew);//将新节点添加到根节点里面 30 31 XmlElement titlenew = xmldoc.CreateElement("title"); 32 titlenew.InnerText = "newtitle"; 33 xmlnew.AppendChild(titlenew);//在book字节点下面继续添加子节点 34 XmlElement authornew = xmldoc.CreateElement("author"); 35 authornew.InnerText = "newauthor"; 36 xmlnew.AppendChild(authornew);//在book字节点下面继续添加子节点 37 XmlElement pricenew = xmldoc.CreateElement("price"); 38 pricenew.InnerText = "100k"; 39 xmlnew.AppendChild(pricenew);//在book字节点下面继续添加子节点 40 41 SaveXML(xmldoc,@"D:\Practice\Test20150703\AboutXML\AboutXML\book.xml");//保存并刷新 42 #endregion 43 break; 44 case "delete"://删除 45 #region 46 //想要删除某一个结点,直接找到其父结点,然后调用RemoveChild方法即可,现在关键的问题是如何找到这个结点,上面的SelectSingleNode可以传入一个Xpath表,我们通过书的ISBN号来找到这本书所在的结点 47 string xmlPath = string.Format("/bookstore/book[@Type=\"{0}\" and @ISBN=\"{1}\"]", GridView1.Rows[GridView1.Rows.Count - 1].Cells[0].Text, GridView1.Rows[GridView1.Rows.Count - 1].Cells[1].Text); 48 XmlNode xmldelete = xmldoc.DocumentElement.SelectSingleNode(xmlPath);//"/bookstore/book[@ISBN=\"{0}\"]"是一个Xpath表达式,找到类型为所选那一行类型的那本书 49 if (xmldelete != null) 50 { 51 xmldelete.ParentNode.RemoveChild(xmldelete); 52 } 53 SaveXML(xmldoc,@"D:\Practice\Test20150703\AboutXML\AboutXML\book.xml");//保存并刷新 54 #endregion 55 break; 56 case "update"://修改 57 #region 58 //修改某条数据的话,首先也是用Xpath表达式找到所需要修改的那一个结点,然后如果是元素的话,就直接对这个元素赋值,如果是属性的话,就用SetAttribute方法设置即可 59 60 //方法1 61 string xmlpath = string.Format("/bookstore/book[@Type=\"{0}\"]", GridView1.Rows[GridView1.Rows.Count - 1].Cells[0].Text); 62 XmlNode updatenode = xmldoc.DocumentElement.SelectSingleNode(xmlpath); 63 updatenode.Attributes.GetNamedItem("Type").InnerText = "testtype"; 64 if (updatenode.ChildNodes != null & updatenode.ChildNodes.Count > 0) 65 { 66 updatenode.ChildNodes.Item(0).InnerText = "testtitle"; 67 } 68 69 //或方法2 70 //XmlElement updateattri = (XmlElement)xmldoc.DocumentElement.SelectSingleNode(xmlpath); 71 //updateattri.SetAttribute("Type", "修改类型"); 72 //updateattri.GetElementsByTagName("title").Item(0).InnerText = "titleupdate";//注意这里只能用InnerText进行修改而不能用value进行修改 73 //updateattri.GetElementsByTagName("author").Item(0).InnerText = "authorupdate"; 74 75 SaveXML(xmldoc,@"D:\Practice\Test20150703\AboutXML\AboutXML\book.xml");//保存并刷新 76 #endregion 77 break; 78 default: //查询 79 #region 80 81 List<BookModel> booklist = new List<BookModel>();//书本集合 82 foreach (XmlNode child in childs) 83 { 84 BookModel book = new BookModel(); 85 XmlElement xe = (XmlElement)child;//将节点转换为元素,便于得到节点的属性值 86 book.BookType = xe.GetAttribute("Type"); 87 book.BookISBN = xe.GetAttribute("ISBN"); 88 89 XmlNodeList schild = child.ChildNodes; 90 if (schild != null && schild.Count > 0) 91 { 92 book.BookName = schild.Item(0).InnerText; 93 book.BookAuthor = schild.Item(1).InnerText; 94 book.BookPrice = schild.Item(2).InnerText; 95 } 96 else 97 { 98 book.BookName = ""; 99 book.BookAuthor = ""; 100 book.BookPrice = ""; 101 } 102 booklist.Add(book); 103 } 104 GridView1.DataSource = booklist; 105 GridView1.DataBind(); 106 #endregion 107 break; 108 } 109 } 110 111 //保存xml 112 private void SaveXML(XmlDocument xmldoc, string savePath) 113 { 114 xmldoc.Save(savePath);//保存 115 OperationXML("select");//刷新 116 }
另外,如果想获取XML相对路径,可以这样做,首先引用命名空间using System.IO; 然后直接 stirng xmlPath = Server.MapPath("Gun.xml") 即可。
3.各个调用事件如下:
//查询节点 protected void Button1_Click(object sender, EventArgs e) { OperationXML("select"); } //新增节点 protected void Button2_Click(object sender, EventArgs e) { OperationXML("create"); } //修改节点 protected void Button3_Click(object sender, EventArgs e) { OperationXML("update"); } //删除节点 protected void Button4_Click(object sender, EventArgs e) { OperationXML("delete"); }
转自:http://www.cnblogs.com/a1656344531/archive/2012/11/28/2792863.html