使用C#操作XML文档,主要就是利用XmlNode及它的子类,XmlDoc等等,对文档的各个部分进行操作。
本文主要讲述了如何使用C#对XMl文档进行增删查改和遍历。
一,增加元素
其实,在XML文档中增加元素有着十分简单的步骤,只要按照步骤操作就可以轻松的对XML中的节点进行增加。
第一步,创建元素。
第二步,设置元素属性。
第三步设置元素父节点。
具体代码如下:
static void CreatNodes(XMLOperation xmlOp)
{
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1") == null)
{
//第一步,创建元素
var xmlEle = xmlOp.xmlDoc.CreateElement("testEle1");
//第二步,设置元素属性
xmlEle.SetAttribute("val1", "1");
//第三步设置元素父节点,这里它的父节点可以是任意的一个节点,父节点就确定了这个元素所在的位置
//这里我们在test节点下去扩展节点
xmlOp.xmlDoc.SelectSingleNode("test").AppendChild(xmlEle);
Console.WriteLine(String.Format("已添加:name:{0}", xmlEle.Name));
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle2") == null)
{
//第一步,创建元素
var xmlEle = xmlOp.xmlDoc.CreateElement("testEle2");
//第二步,设置元素属性
xmlEle.SetAttribute("val2", "2");
//第三步设置元素父节点,这里它的父节点可以是任意的一个节点,父节点就确定了这个元素所在的位置
//这里我们在test节点下去扩展节点
xmlOp.xmlDoc.SelectSingleNode("test").AppendChild(xmlEle);
Console.WriteLine(String.Format("已添加:name:{0}", xmlEle.Name, xmlEle.Value));
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
}
二,遍历文档
实际上,遍历XML文档就是遍历树形结构。采用递归的方式,是最为简单的一种遍历方式。
这里,我想要着重提一下,不要轻易用XmlElement强制转换XmlNode。因为XmlNode是基类,但是它不仅仅只有一个子类,而XmlElement只是它的一个子类而已。如果这个XmlNode的TYPE是Doc的话,那么强制装换就会抛出异常。正确的做法,是先判断类型,再进行强制转换。具体使用,见下面的代码。
static void ReadNodes(XmlNode root)
{
//读取节点的方式可以是选择节点SelectSingleNode,然后再GetAttribute()去读取内容
//这里采用遍历的方式去读取
if (root == null)
return;
XmlElement rootEle;
//这个地方不要直接强制转换,因为XmlNode是XmlEle的基类
//所以,直接转换会非常容易抛出异常
if (root.NodeType == XmlNodeType.Element)
{
rootEle = root as XmlElement;
foreach (XmlAttribute att in rootEle.Attributes)
Console.WriteLine(String.Format("遍历:name:{0}, val: {1}", att.Name, att.Value));
}
foreach (XmlNode child in root.ChildNodes)
ReadNodes(child);
}
三,删除节点
如果想要删除节点,那么其实只需要知道节点的名称就可以进行删除了。
具体代码如下:
static void DeleteNodes(XMLOperation xmlOp)
{
//删除节点也有两种方式,可以使用select的方式,也可以使用遍历的方式删除
//这里使用select的方式删除
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1") != null)
{
var ele=xmlOp.xmlDoc.SelectSingleNode("test").RemoveChild(xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1"));
if(ele.NodeType == XmlNodeType.Element)
Console.WriteLine(String.Format("已删除:name:{0}", ele.Name));
}
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
四,修改节点属性
其实修改节点就是对节点的属性进行修改,其中,属性的修改只能修改val 不能修改name。如果要修改name就要去除这个属性,然后再添加新的名称属性。
具体代码如下:
static void ModifyNodes(XmlNode root)
{
//其实修改节点就是对节点的属性进行修改
//其中,属性的修改只能修改val 不能修改name。如果要修改name就要去除这个属性,然后再添加新的名称属性
//这个地方我们采用遍历的方式对name=test2的属性进行修改
if (root == null)
return;
XmlElement rootEle;
//这个地方不要直接强制转换,因为XmlNode是XmlEle的基类
//所以,直接转换会非常容易抛出异常
if (root.NodeType == XmlNodeType.Element)
{
rootEle = root as XmlElement;
foreach (XmlAttribute att in rootEle.Attributes)
{
if (att.Name == "val2")
{
att.Value = "3";
Console.WriteLine(String.Format("已修改:name:{0}, val: {1}", att.Name, att.Value));
}
}
}
foreach (XmlNode child in root.ChildNodes)
ModifyNodes(child);
}
在讨论了每一种操作之后,我们来看看综合的操作方法和代码吧。VS工程请在我上传的资源里面查找,这里只贴主要代码:
类 XMLOperation
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace XMLOperation
{
class XMLOperation
{
public XmlDocument xmlDoc;
public string fileName;
public XMLOperation(string fileName="XMLTest.xml")
{
this.fileName = fileName;
xmlDoc = new XmlDocument();
if (File.Exists(fileName))
{
xmlDoc.Load(fileName);
}
else
{
XmlDeclaration xmlDec = xmlDoc.CreateXmlDeclaration("1.0", "gb2312", null);
xmlDoc.AppendChild(xmlDec);
//最少加入一个根元素,不然保存的时候会抛出异常
var ele = xmlDoc.CreateElement("test");
xmlDoc.AppendChild(ele);
}
//保存文件
xmlDoc.Save(fileName);
}
}
}
类Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace XMLOperation
{
class Program
{
static void Main(string[] args)
{
XMLOperation xmlOp = new XMLOperation();
//增加节点
CreatNodes(xmlOp);
//遍历读取节点
ReadNodes(xmlOp.xmlDoc);
//删除节点
DeleteNodes(xmlOp);
//修改节点
ModifyNodes(xmlOp.xmlDoc);
xmlOp.xmlDoc.Save(xmlOp.fileName);
Console.ReadKey();
}
static void CreatNodes(XMLOperation xmlOp)
{
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1") == null)
{
//第一步,创建元素
var xmlEle = xmlOp.xmlDoc.CreateElement("testEle1");
//第二步,设置元素属性
xmlEle.SetAttribute("val1", "1");
//第三步设置元素父节点,这里它的父节点可以是任意的一个节点,父节点就确定了这个元素所在的位置
//这里我们在test节点下去扩展节点
xmlOp.xmlDoc.SelectSingleNode("test").AppendChild(xmlEle);
Console.WriteLine(String.Format("已添加:name:{0}", xmlEle.Name));
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle2") == null)
{
//第一步,创建元素
var xmlEle = xmlOp.xmlDoc.CreateElement("testEle2");
//第二步,设置元素属性
xmlEle.SetAttribute("val2", "2");
//第三步设置元素父节点,这里它的父节点可以是任意的一个节点,父节点就确定了这个元素所在的位置
//这里我们在test节点下去扩展节点
xmlOp.xmlDoc.SelectSingleNode("test").AppendChild(xmlEle);
Console.WriteLine(String.Format("已添加:name:{0}", xmlEle.Name, xmlEle.Value));
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
}
static void DeleteNodes(XMLOperation xmlOp)
{
//删除节点也有两种方式,可以使用select的方式,也可以使用遍历的方式删除
//这里使用select的方式删除
if (xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1") != null)
{
var ele=xmlOp.xmlDoc.SelectSingleNode("test").RemoveChild(xmlOp.xmlDoc.SelectSingleNode("test").SelectSingleNode("testEle1"));
if(ele.NodeType == XmlNodeType.Element)
Console.WriteLine(String.Format("已删除:name:{0}", ele.Name));
}
xmlOp.xmlDoc.Save(xmlOp.fileName);
}
static void ModifyNodes(XmlNode root)
{
//其实修改节点就是对节点的属性进行修改
//其中,属性的修改只能修改val 不能修改name。如果要修改name就要去除这个属性,然后再添加新的名称属性
//这个地方我们采用遍历的方式对name=test2的属性进行修改
if (root == null)
return;
XmlElement rootEle;
//这个地方不要直接强制转换,因为XmlNode是XmlEle的基类
//所以,直接转换会非常容易抛出异常
if (root.NodeType == XmlNodeType.Element)
{
rootEle = root as XmlElement;
foreach (XmlAttribute att in rootEle.Attributes)
{
if (att.Name == "val2")
{
att.Value = "3";
Console.WriteLine(String.Format("已修改:name:{0}, val: {1}", att.Name, att.Value));
}
}
}
foreach (XmlNode child in root.ChildNodes)
ModifyNodes(child);
}
static void ReadNodes(XmlNode root)
{
//读取节点的方式可以是选择节点SelectSingleNode,然后再GetAttribute()去读取内容
//这里采用遍历的方式去读取
if (root == null)
return;
XmlElement rootEle;
//这个地方不要直接强制转换,因为XmlNode是XmlEle的基类
//所以,直接转换会非常容易抛出异常
if (root.NodeType == XmlNodeType.Element)
{
rootEle = root as XmlElement;
foreach (XmlAttribute att in rootEle.Attributes)
Console.WriteLine(String.Format("遍历:name:{0}, val: {1}", att.Name, att.Value));
}
foreach (XmlNode child in root.ChildNodes)
ReadNodes(child);
}
}
}
程序输出结果如下图:
最后,在工程的Debug目录下,会出现一个一个XMLTest.xml的文档