文章目录
- XML样例
- 获取整个文档根开始
- 获取根节点
- 获取最后一个子节点
- 在同级之间向前导航
- 在同级之间向后导航
- 查找节点
- 获取多个节点
- 编辑节点
- 添加节点
- 删除节点
- 小结
- 附录参考
在项目的实际应用中,有很多数据都会保存为XML配置文件。使用率比较高的操作有加载文档,
读取文档,读取XML的某个节点或属性值,增加或插入一个节点,遍历节点信息等。
XML样例
后面的例子以该xml文档为基础进行演示,在这里我将它放在D:\temp.xml路径下。请注意这个XML文档样例中包含了XmlComment 注释
,XmlElement 元素
,和XmlCDataSection 字符数字段
,这些类型同属于节点
。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Citys>
<!--这是一份关于城市省份的文件-->
<Province level="发达">广东
<City level="省会">广州</City>
<City level="一线">深圳</City>
</Province>
<Province level="发展">广西
<![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
<City level="三线">桂林</City>
</Province>
</Citys>
以下示例演示如何获取根节点,跳转到根节点的第一个子节点、访问其任何子节点、返回到父结点,然后跨同级节点导航。
获取整个文档根开始
演示加载文档,然后使用该对象将文档的内容打印输出到控制台。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//使用document节点将文档内容输出到控制台
Console.WriteLine(document.DocumentElement.OuterXml);
控制台输出结果:
获取根节点
演示了如何跳转到根节点的第一个子节点,然后循环访问该节点的子节点。(如果该节点有子节点的话)。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//第一个子节点
XmlElement root = document.DocumentElement;
if(root.HasChildNodes)
{//如果有子节点
for(int i=0; i<root.ChildNodes.Count; i++)
{ //展示子节点的内容
Console.WriteLine(root.ChildNodes[i].InnerText);
}
示例中root
的值是Citys
, 可以从结果中看到该节点下的子节点都会被遍历出来,无论节点类型是XmlElement
元素,还是XmlComment
注释,或是XmlCDataSection
字符数字段。
运行结果:
这是一份关于城市省份的文件
广东广州深圳
广西All Jane Austen novels 25% off starting 3/23!桂林
获取最后一个子节点
<Province level="发展">广西</Province>
是最后一个子节点。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//第一个子节点
XmlElement root = document.DocumentElement;
if(root.HasChildNodes)
{//如果有子节点
XmlNode lastChild = root.LastChild;
Console.WriteLine("显示最后一个节点元素:");
Console.WriteLine(lastChild.OuterXml);
}
运行结果
显示最后一个节点元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>
在同级之间向前导航
在xml样例中可以看到注释结点和城市节点City是属于同级节点的。很多情况下我们的xml文件没有添加注释或其它字符数值段,就很容易将它们忽略掉,实际上这些类型也是属于节点。FirstChild
使用NextSibling
向前导航。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//根节点
XmlElement root = document.DocumentElement;
//第一个节点
XmlNode currNode = root.FirstChild;
Console.WriteLine("显示第一个节点元素:");
Console.WriteLine(currNode.OuterXml);
//相邻节点
XmlNode nextNode = currNode.NextSibling;
Console.WriteLine("\r\n显示相邻节点元素:");
Console.WriteLine(nextNode.OuterXml);
运行结果
显示第一个节点元素:
<!--这是一份关于城市省份的文件-->
显示相邻节点元素:
<Province level="发达">广东<City level="省会">广州</City><City level="一线">深圳</City></Province>
在同级之间向后导航
LastChild
使用PreviousSibling
向后导航。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//根节点
XmlElement root = document.DocumentElement;
XmlNode currNode = root.LastChild;
Console.WriteLine("显示最后一个节点元素:");
Console.WriteLine(currNode.OuterXml);
XmlNode nextNode = currNode.PreviousSibling;
Console.WriteLine("\r\n显示相邻节点元素:");
Console.WriteLine(nextNode.OuterXml);
运行结果:
显示最后一个节点元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>
显示相邻节点元素:
<Province level="发达">广东<City level="省会">广州</City><City level="一线">深圳</City></Province>
查找节点
可以根据XPath
查询字符串来查找一个或多个数据节点。
附录:XPath的表达式MSDN介绍 https://learn.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/ms256086(v=vs.100)?redirectedfrom=MSDN
获取单个节点
演示使用知道节点路径以及是第几个节点来找到省份。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//找Citys元素下的第2个Province元素
string xPath = "Citys/Province[2]";
XmlNode currNode = document.SelectSingleNode(xPath);
if(currNode != null)
{
Console.WriteLine("寻找到的元素:");
Console.WriteLine(currNode.OuterXml);
}
运行结果
寻找到的元素:
<Province level="发展">广西<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="三线">桂林</City></Province>
还可以使用GetElementById
来搜索节点。如果使用这个方法,必须在XML文件的文档类型定义声明中定义ID。
将示例中的XML文档修改如下,此时将Province
节点下的level
声明为ID了。
附录:关于GetElementById的MSDN示例
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys [
<!ELEMENT Province ANY>
<!ATTLIST Province level ID #REQUIRED> ]>
<Citys>
<!--这是一份关于城市省份的文件-->
<Province level="发达">广东
<City level="省会">广州</City>
<City level="一线">深圳</City>
</Province>
<Province level="发展">广西
<![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
<City level="三线">桂林</City>
</Province>
</Citys>
使用GetElementById
来搜索ID值是发达的节点
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//根据(level)ID来搜索节点
XmlElement findEle = document.GetElementById("发达");
if(findEle != null)
{
Console.WriteLine("寻找到的元素:");
Console.WriteLine(findEle.OuterXml);
}
运行结果:
寻找到的元素:
<Province level="发达">广东
<City level="省会">广州</City><City level="一线">深圳</City></Province>
获取多个节点
在这里使用SelectNodes
选择所有Province
的节点。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
XmlNodeList nodeList;
//获取根节点
XmlElement root = document.DocumentElement;
nodeList = root.SelectNodes("Province");
foreach(XmlNode node in nodeList)
{
//打印节点及其所有子节点的串联值
Console.WriteLine(node.InnerText);
}
运行结果:
广东
广州深圳
广西
All Jane Austen novels 25% off starting 3/23!桂林
还可以使用GetElementsByTagName
通过节点的名称获取节点的集合。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
XmlNodeList nodeList;
//获取根节点
XmlElement root = document.DocumentElement;
nodeList = root.GetElementsByTagName("Province");
foreach(XmlNode node in nodeList)
{
//打印节点及其所有子节点的串联值
Console.WriteLine(node.InnerText);
}
运行结果同上。
编辑节点
获取某一个(广州)节点,并增加其属性,以及更改原有属性的值。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
XmlNodeList nodeList;
//根节点
XmlElement root = document.DocumentElement;
nodeList = root.GetElementsByTagName("City");
if(nodeList.Count > 0)
{
// 获取广州节点
XmlElement element = (XmlElement) nodeList[0];
//添加新的属性
element.SetAttribute("newAttr1", "One");
element.SetAttribute("newAttr2", "Two");
element.SetAttribute("newAttr3", "Three");
//已存在属性的值
element.Attributes["level"].InnerText = "南方";
}
document.Save(@"D:\temp.xml");
运行结果:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys[
<!ELEMENT Province ANY>
<!ATTLIST Province level ID #REQUIRED> ]>
<Citys>
<!--这是一份关于城市省份的文件-->
<Province level="发达">广东
<City level="南方" newAttr1="One" newAttr2="Two" newAttr3="Three">广州</City>
<City level="一线">深圳</City></Province>
<Province level="发展">广西
<![CDATA[All Jane Austen novels 25% off starting 3/23!]]><City level="省会">桂林</City></Province>
</Citys>
添加节点
可以使用CreateElement
方法或CreateNode
方法添加节点。
对于任何其他数据类型的节点(比如注释、空格节点或CDATA节点),请使用CreateNode
方法。
演示了创建一个省份节点,以及一个城市节点,向这两个节点添加属性,并将节点添加到文档。
//创建XML文档对象
XmlDocument document = new XmlDocument();
//加载整个文档
document.Load(@"D:\temp.xml");
//根节点
XmlElement root = document.DocumentElement;
//创建省份节点
XmlElement proEle = document.CreateElement("Province");
//设置元素值
proEle.InnerText = "甘肃";
//设置属性
proEle.SetAttribute("level", "西北");
proEle.SetAttribute("Attr5", "测试");
//创建城市节点
XmlElement cityEle = document.CreateElement( "City");
cityEle.InnerText = "兰州";
cityEle.SetAttribute("level", "拉面");
//将城市节点添加到省份中
proEle.AppendChild(cityEle);
//将省份节点添加到根节点末尾
root.AppendChild(proEle);
document.Save(@"D:\temp.xml");
运行结果:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!DOCTYPE Citys[
<!ELEMENT Province ANY>
<!ATTLIST Province level ID #REQUIRED> ]>
<Citys>
<!--这是一份关于城市省份的文件-->
<Province level="发达">广东
<City level="海南" newAttr1="One" newAttr2="Two" newAttr3="Three">广州</City>
<City level="一线">深圳</City>
</Province>
<Province level="发展">广西
<![CDATA[All Jane Austen novels 25% off starting 3/23!]]>
<City level="省会">桂林</City>
</Province>
<Province level="西北" Attr5="测试">甘肃
<City level="拉面">兰州</City>
</Province>
</Citys>
删除节点
使用RemoveChild
方法删除节点。
/// <summary>
/// 删除一个省份,以及该节点前面出现的空格
/// </summary>
/// <param name="province"></param>
public void DeleteProvince(XmlNode province)
{
//前一个节点
XmlNode preNode = province.PreviousSibling;
//删除省份节点
province.OwnerDocument.DocumentElement.RemoveChild(province);
if(preNode.NodeType == XmlNodeType.Whitespace ||
preNode.NodeType == XmlNodeType.SignificantWhitespace)
{//删除空格
preNode.OwnerDocument.DocumentElement.RemoveChild(preNode);
}
}
小结
函数名或类名 | 描述 |
XmlDocument | XML文档对象 |
XmlDocument.DocumentElement | 文档树的根 |
CreateElement (CreateNode) | 创建结点 |
PreviousSibling (NextSibling) | 同级节点之间的前(后)相邻节点 |
SelectSingleNode(与XPath配合使用) | 查找单个节点 |
GetElementById (与ID配合使用) | 查找单个节点 |
SelectNodes(与XPath配合使用) | 查找多个节点 |
GetElementsByTagName(与节点名称配合使用) | 查找多个节点 |
element.InnerText = "甘肃"; element.SetAttribute("Attr5", "测试") | 编辑节点 |
InsertAfter (InsertBefore) | 定位节点 |
RemoveChild | 删除节点 |
附录参考
1 XPath的使用 XPath的表达式MSDN介绍 https://learn.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/ms256086(v=vs.100)?redirectedfrom=MSDN
2 XML文件的文档类型定义声明中定义ID 关于GetElementById的MSDN示例
3 XmlDocument 类 的介绍 https://learn.microsoft.com/zh-cn/dotnet/api/system.xml.xmldocument?view=net-7.0