.Net 中有 System.Xml 命名空间为处理XML提供基于标准的支持。
XmlDocument : 可使用此类在文档中加载、验证、编辑、添加和放置 XML。
XmlElement : 表示一个元素。
XmlNode : 表示 XML 文档中的单个节点。
XmlReader : 表示提供对 XML 数据进行快速、非缓存、只进访问的读取器。
XmlWriter : 表示一个写入器,该写入器提供一种快速、非缓存和只进方式以生成包含 XML 数据的流或文件。
以下的范例代码,无特殊说明,均为我自定义的一个 XmlUtil 类的方法。
这个类有两个重要的属性:
#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
有两种方法
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 />
/// <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文件成功
使用 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文件成功
/// <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>
功能代码
/// <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>
功能代码
/// <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>
功能代码
/// <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 = 张三
步骤:
/// <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