[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方法

功能代码:

使用本方法的前提是先调用 CreateXmlDocumentOpenXmlDocument,以初始化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< stringstring> 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< stringstring> 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< stringstring> attributes =  new Dictionary< stringstring>();
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 

你可能感兴趣的:([C#]XML操作)