标签:
前言
命名空间
.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
创建XML文件
步骤:
- 创建一个XmlDocument对象
- 写入内容
- 使用 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文件
步骤:
- 创建一个 XmlDocument 对象
- 用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文件
使用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文件成功");
}
测试结果:
输出
增
步骤:
- 创建 XmlDocument 对象
- 调用 XmlDocument 类的 CreateElement 方法创建新节点
- 调用 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>
改
改节点值
步骤:
- 创建一个 XmlDocument 对象
- 通过 SelectSingleNode 方法找到指定节点
- 给 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>
改节点属性
步骤:
- 创建一个 XmlDocument 对象
- 通过 SelectSingleNode 方法找到指定节点
- 通过 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>
查
查找节点的值
步骤:
- 通过 SelectSingleNode 方法找到节点
- 读取 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);
测试结果
输出
查找节点属性的值
步骤:
- 通过 SelectSingleNode 方法找到节点
- 用节点的Attributes属性初始化XmlAttributeCollection类
- 查找指定的属性名,修改其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操作
标签:
原文地址:http://www.cnblogs.com/jingmoxukong/p/4919467.html