转载

[C#]XML操作

前言

命名空间

.Net 中有 System.Xml 命名空间为处理XML提供基于标准的支持。

常用类

XmlDocument 可使用此类在文档中加载、验证、编辑、添加和放置 XML。

XmlElement 表示一个元素。

XmlNode 表示 XML 文档中的单个节点。

XmlReader 表示提供对 XML 数据进行快速、非缓存、只进访问的读取器。

XmlWriter 表示一个写入器,该写入器提供一种快速、非缓存和只进方式以生成包含 XML 数据的流或文件。

本文说明

以下的范例代码,无特殊说明,均为我自定义的一个 XmlUtil 类的方法。

这个类有两个重要的属性:

  • Xml 文件的路径
  • XmlDocument 对象
#region 对象、属性 /// <summary> /// XmlUtil类加载的XML文件 /// </summary> private string _filePath = null; /// <summary> /// XmlUtil类持有的XmlDocument对象 /// </summary> private XmlDocument _xmlDoc = null; /// <summary> /// XmlUtil类加载的XML文件 /// </summary> public string FilePath {  get { return this._filePath; }  set { this._filePath = value; } } /// <summary> /// XmlUtil类持有的XmlDocument对象 /// </summary> public XmlDocument XmlDoc {  get { return this._xmlDoc; }  set { this._xmlDoc = value; } } #endregion 

创建XML文件

步骤: 

  1. 创建一个 XmlDocument 对象
  2. 写入内容
  3. 使用  XmlDocument   类的  Save 方法保存内容

有两种方法

例1:加载xml文件内容字符串,创建xml文档

XmlDocument doc = new XmlDocument(); doc.LoadXml("<book ISBN='1-861001-57-5'>" +             "<title>Pride And Prejudice</title>" +             "<price>19.95</price>" +             "</book>"); doc.Save("d://result.xml");

这种方法的缺点在于,你必须保证 LoadXml 方法加载的xml内容格式必须正确。  

例2:创建一个xml文档   

功能代码

/// <summary> /// 如果文件不存在则创建一个带有根节点的Xml 文件,如果文件存在,则打开XML文件 /// </summary> /// <param name="filePath">文件路径</param> /// <param name="rootName">根节点名</param> /// <returns>0表示成功,其他为失败</returns> public int CreateXmlDocument(string filePath, string rootName) {     if (string.IsNullOrEmpty(filePath)) {  return -1;     }     // 如果文件存在,则直接打开     if (File.Exists(filePath)) {  return this.OpenXmlDocument(filePath);     }     try {  this._xmlDoc = new XmlDocument();  // 创建声明节点  XmlDeclaration xmldecl = this._xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);  this._xmlDoc.AppendChild(xmldecl);  // 创建根节点  XmlElement xmlRoot = this._xmlDoc.CreateElement("", rootName, "");  this._xmlDoc.AppendChild(xmlRoot);  // 保存  this._xmlDoc.Save(filePath);  this.FilePath = filePath;  return 0;     } catch (Exception ex) {  Console.WriteLine(ex.Message);  return -1;     } } 

测试代码 

XmlUtil util = new XmlUtil(); int code = util.CreateXmlDocument("D://temp//class.xml", "Configuration");

测试结果

创建class.xml文件成功,内容如下:

<?xml version="1.0" encoding="utf-8"?> <Configuration />

打开XML文件

步骤:

  1. 创建一个 XmlDocument 对象
  2. XmlDocument 类的 Load 方法加载指定xml文件的路径

功能代码

/// <summary> /// 打开XML文档 /// </summary> /// <param name="filePath">文件路径</param> /// <returns>0表示成功,其他为失败</returns> public int OpenXmlDocument(string filePath) {  if (string.IsNullOrEmpty(filePath)) {   return -1;  }  if (!File.Exists(filePath)) {   return -1;  }  try {   this._xmlDoc = new XmlDocument();   this._xmlDoc.Load(filePath);   this.FilePath = filePath;   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  }   } 

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {     Console.WriteLine("打开XML文件成功"); }

测试结果

输出

打开XML文件成功

保存XML文件

使用 XmlDocument 类的 Save 方法

功能代码:

使用本方法的前提是先调用 CreateXmlDocument OpenXmlDocument ,以初始化xml文件路径和XmlDoc属性。

/// <summary> /// 保存XML文档 /// </summary> /// <returns>0表示成功,其他为失败</returns> public int SaveXmlDocument() {  if (null == this._xmlDoc || string.IsNullOrEmpty(this.FilePath)) {   return -1;  }  try {   this._xmlDoc.Save(this.FilePath);   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  }   } 


测试代码:

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {     Console.WriteLine("打开XML文件成功"); } code = util.SaveXmlDocument(); if (0 == code) {     Console.WriteLine("保存XML文件成功"); }

测试结果:

输出

打开XML文件成功保存XML文件成功

步骤:

  1. 创建 XmlDocument 对象
  2. 调用 XmlDocument 类的  CreateElement   方法创建新节点
  3. 调用  XmlDocument  类的  AppendChild 方法将新节点加到一个已存在的节点下

功能代码

/// <summary> /// 在一个已存在的节点下新增XML节点。如果key节点在父节点下已存在,则返回失败 /// </summary> /// <param name="parent">要插入元素的父节点路径。类似"Class/Student",不要包含根节点。如果为空,则key节点会插入根节点下。</param> /// <param name="key">要插入元素的key</param> /// <param name="value">要插入元素的value,如果为空。则key节点会是一个空节点。</param> /// <param name="attributes">要插入元素的属性。如果为null,key节点没有属性值</param> /// <returns>0为成功,其他为失败</returns> public int InsertNewNodeToXml(string parent, string key, string value, Dictionary<string, string> attributes) {    if (null == this._xmlDoc || string.IsNullOrEmpty(key)) {   return -1;  }  try {   // 如果parent为空,则将节点key插入根节点下   XmlElement root = this._xmlDoc.DocumentElement;   XmlNode parentNode = null;   if (string.IsNullOrEmpty(parent)) {    parentNode = root;   } else {    // 获取父节点    parentNode = root.SelectSingleNode(parent);    if (null == parentNode) {     Console.WriteLine("未找到父节点");     return -1;    }   }   // 如果要插入的node已存在,结束方法   XmlNode newNode = parentNode.SelectSingleNode(key);   if (null != newNode) {    return -1;   }   // 创建key节点,并设置它的value   XmlElement elem = this._xmlDoc.CreateElement(key);   if (!string.IsNullOrEmpty(value)){    elem.InnerText = value;   }   // 遍历属性字典,设置key节点的属性   if (null != attributes && 0 != attributes.Count) {    foreach(KeyValuePair<string, string> kv in attributes){     XmlAttribute newAttribute = this._xmlDoc.CreateAttribute(kv.Key);     newAttribute.Value = kv.Value;     elem.SetAttributeNode(newAttribute);    }   }   // 将新节点添加到父节点   parentNode.AppendChild(elem);   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

以下两个测试例的xml初始内容一样,如下:

<?xml version="1.0" encoding="utf-8"?> <Configuration />

测试一代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } Dictionary<string, string> attributes = new Dictionary<string, string>(); attributes.Add("name", "张三"); attributes.Add("sex", "男"); attributes.Add("age", "22"); code = util.InsertNewNodeToXml("", "Class", ""); code = util.InsertNewNodeToXml("Class", "Student", "张三", attributes); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="张三" sex="男" age="22">张三</Student>   </Class> </Configuration>

测试二代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } code = util.InsertNewNodeToXml("", "Class", ""); code = util.InsertNewNodeToXml("Class", "Student", "张三", null); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student>张三</Student>   </Class> </Configuration>

删除节点

XmlElement  XmlNode 两个类都提供了以下两个方法:

RemoveChild ,删除一个指定的子节点。

RemoveAll ,删除所有子节点。

功能代码

/// <summary> /// 删除prefix节点下所有的指定节点和它的所有子节点 /// </summary> /// <param name="prefix">前驱节点,如果不指定,默认为根节点。形式为类似Class/Student</param> /// <param name="key">要删除的节点的键</param> /// <param name="value">要删除的节点的值,如果value为空,则删除所有节点名为key的节点</param> /// <returns>0为成功,其他为失败</returns> public int RemoveNode(string prefix, string key, string value) {  if (null == this._xmlDoc || string.IsNullOrEmpty(key)) {   return -1;  }  try {   // 获取前驱节点并校验   XmlNode prefixNode = this._xmlDoc.DocumentElement;   if (!string.IsNullOrEmpty(prefix)) {    prefixNode = this._xmlDoc.DocumentElement.SelectSingleNode(prefix);   }   if (null == prefixNode) {    return -1;   }   XmlNode parentNode = null;   XmlNodeList nodes = prefixNode.ChildNodes;   for (int i = 0; i < nodes.Count; i++) {    XmlNode node = nodes[i];    if (node.Name.Equals(key)) {     if (string.IsNullOrEmpty(value)) {      parentNode = node.ParentNode;      node.RemoveAll();      parentNode.RemoveChild(node);      i--; // 删除节点后,其他元素下标会改变     } else {      if (node.InnerText.Equals(value)) {       parentNode = node.ParentNode;       node.RemoveAll();       parentNode.RemoveChild(node);       i--; // 删除节点后,其他元素下标会改变      }     }    }   }   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml文件内容:

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>    <Student>张三</Student>    <Student>李四</Student>    <Student>王五</Student>    <Student>张三</Student>    <Student>李四</Student>    <Student>王五</Student>   </Class> </Configuration> 

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } code = util.RemoveNode("Class", "Student", "张三"); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student>李四</Student>     <Student>王五</Student>     <Student>李四</Student>     <Student>王五</Student>   </Class> </Configuration>

删除属性

XmlElement  提供了以下方法删除属性:

RemoveAttribute

RemoveAllAttributes

RemoveAttributeAt

RemoveAttributeNode

例: 删除一个指定节点的属性

功能代码

/// <summary> /// 删除名为key的节点的attribute属性 /// </summary> /// <param name="key">节点key</param> /// <param name="attribute">节点attribute</param> public int RemoveAttribute(string key, string attribute) {  if (null == this._xmlDoc || string.IsNullOrEmpty(key) || string.IsNullOrEmpty(attribute)) {   return -1;  }  try {   // 获取前驱节点并校验   XmlElement keyElem = (XmlElement)this._xmlDoc.DocumentElement.SelectSingleNode(key);   if (null == keyElem) {    return -1;   }   keyElem.RemoveAttribute(attribute);   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml文件内容:

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="李四" age="27" sex="男">李四</Student>   </Class> </Configuration>

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } code = util.RemoveAttribute("Class/Student", "age"); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="李四" sex="男">李四</Student>   </Class> </Configuration>

改节点值

步骤:

  1. 创建一个 XmlDocument 对象
  2. 通过  SelectSingleNode 方法找到指定节点
  3. 给  InnerText 属性赋值

功能代码

/// <summary> /// 修改所有值为oldValue的key节点,新值为newValue /// </summary> /// <param name="prefix">前驱路径</param> /// <param name="key">节点key</param> /// <param name="oldValue">旧值</param> /// <param name="newValue">新值</param> /// <returns>0表示成功,其他为失败</returns> public int SetXmlNodeValue(string prefix, string key, string oldValue, string newValue) {  if (null == this._xmlDoc || string.IsNullOrEmpty(key)   || string.IsNullOrEmpty(oldValue) || string.IsNullOrEmpty(newValue)) {   return -1;  }  try {   // 获取前驱节点并校验   XmlNode prefixNode = this._xmlDoc.DocumentElement;   if (!string.IsNullOrEmpty(prefix)) {    prefixNode = this._xmlDoc.DocumentElement.SelectSingleNode(prefix);   }   if (null == prefixNode) {    return -1;   }   XmlNodeList nodes = prefixNode.ChildNodes;   for (int i = 0; i < nodes.Count; i++) {    XmlNode node = nodes[i];    if (node.Name.Equals(key) && node.InnerText.Equals(oldValue)) {     node.InnerText = newValue;    }   }   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml文件内容为:

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>    <Student>张三</Student>    <Student>李四</Student>    <Student>王五</Student>    <Student>张三</Student>    <Student>李四</Student>    <Student>王五</Student>   </Class> </Configuration> 

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } code = util.SetXmlNodeValue("Class", "Student", "张三", "zhangsan"); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student>zhangsan</Student>     <Student>李四</Student>     <Student>王五</Student>     <Student>zhangsan</Student>     <Student>李四</Student>     <Student>王五</Student>   </Class> </Configuration>

改节点属性

步骤:

  1. 创建一个  XmlDocument  对象
  2. 通过  SelectSingleNode  方法找到指定节点
  3. 通过  SetAttribute 方法给指定的属性设置值

功能代码

/// <summary> /// 设置第一个满足key和attribute的XML节点的值 /// </summary> /// <param name="key">节点key</param> /// <param name="attribute">属性名</param> /// <param name="value">指定节点的特定属性的值</param> /// <returns>0表示成功,其他为失败</returns> public int SetXmlNodeAttributeValue(string key, string attribute, string value) {  if (null == this._xmlDoc || string.IsNullOrEmpty(key)) {   return -1;  }  try {   // 如果parent为空,则将节点key插入根节点下   XmlElement elem = (XmlElement)this._xmlDoc.DocumentElement.SelectSingleNode(key);   if (null == elem) {    return -1;   }   elem.SetAttribute(attribute, value);   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml文件内容:

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="张三", age="18", sex="男">张三</Student>   </Class> </Configuration>

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } code = util.SetXmlNodeAttributeValue("Class/Student", "age", "28"); code = util.SaveXmlDocument(); if (0 == code) {  Console.WriteLine("保存XML文件成功"); } 

测试结果

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="张三" age="28" sex="男">张三</Student>   </Class> </Configuration>

查找节点的值

步骤:

  1. 通过 SelectSingleNode 方法找到节点
  2. 读取  InnerText 属性的值

功能代码

/// <summary> /// 获取第一个满足key的XML节点的值 /// </summary> /// <param name="key">节点key</param> /// <param name="value">出参,指定节点的的值</param> /// <returns>0表示成功,其他为失败</returns> public int GetXmlNodeValue(string key, out string value) {  value = null;  if (null == this._xmlDoc) {   return -1;  }  try {   //根据指定路径获取节点   XmlNode xmlNode = this._xmlDoc.DocumentElement.SelectSingleNode(key);   if (null == xmlNode) {    return -1;   }   value = xmlNode.InnerText;   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml内容

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="张三" age="28" sex="男">张三</Student>   </Class> </Configuration>

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } string value; code = util.GetXmlNodeValue("Class/Student", out value); Console.WriteLine("value = " + value); 

测试结果

输出

打开XML文件成功 value = 张三

查找节点属性的值

步骤:

  1. 通过 SelectSingleNode 方法找到节点
  2. 用节点的 Attributes 属性初始化 XmlAttributeCollection
  3. 查找指定的属性名,修改其value

功能代码

/// <summary> /// 获取第一个满足key和attribute的XML节点的值 /// </summary> /// <param name="key">节点key</param> /// <param name="attribute">属性名</param> /// <param name="value">出参,指定节点的特定属性的值</param> /// <returns>0表示成功,其他为失败</returns> public int GetXmlNodeAttributeValue(string key, string attribute, out string value) {  value = null;  if (null == this._xmlDoc) {   return -1;  }  try {   //根据指定路径获取节点   XmlNode xmlNode = this._xmlDoc.DocumentElement.SelectSingleNode(key);   if (null == xmlNode) {    return -1;   }   //获取节点的属性,并循环取出需要的属性值   XmlAttributeCollection xmlAttr = xmlNode.Attributes;   for (int i = 0; i < xmlAttr.Count; i++) {    if (xmlAttr.Item(i).Name.Equals(attribute)) {     value = xmlAttr.Item(i).Value;     break;    }   }   return 0;  } catch (Exception ex) {   Console.WriteLine(ex.Message);   return -1;  } } 

测试前提

原xml内容

<?xml version="1.0" encoding="utf-8"?> <Configuration>   <Class>     <Student name="张三" age="28" sex="男">张三</Student>   </Class> </Configuration>

测试代码

XmlUtil util = new XmlUtil(); int code = util.OpenXmlDocument("D://temp//class.xml"); if (0 == code && null != util.XmlDoc) {  Console.WriteLine("打开XML文件成功"); } string attributeValue; code = util.GetXmlNodeAttributeValue("Class/Student", "age", out attributeValue); Console.WriteLine("attributeValue = " + attributeValue); 

测试结果

打开XML文件成功 attributeValue = 28

参考资料 

https://msdn.microsoft.com/zh-cn/library/system.xml.aspx

正文到此结束
Loading...