在C#的XML文档处理场景中,SelectNodes和SelectSingleNode是XmlNode类提供的两个用于执行XPath查询的方法,前者用于获取匹配XPath表达式的所有节点集合,后者用于获取匹配的第一个节点,两者都是处理XML数据的常用工具。

方法基本定义
SelectSingleNode方法的作用是执行XPath查询,返回第一个匹配指定表达式的XmlNode对象,如果没有找到匹配的节点则返回null。它的常用重载形式为:
public XmlNode? SelectSingleNode(string xpath); public XmlNode? SelectSingleNode(string xpath, XmlNamespaceManager? nsmgr);
SelectNodes方法的作用是执行XPath查询,返回所有匹配指定表达式的XmlNodeList集合,如果没有找到匹配的节点则返回空集合。它的常用重载形式为:
public XmlNodeList? SelectNodes(string xpath); public XmlNodeList? SelectNodes(string xpath, XmlNamespaceManager? nsmgr);
核心参数说明
- xpath:表示XPath查询表达式的字符串,用于指定要匹配的节点规则,比如节点名称、属性条件、层级关系等。
- nsmgr:可选参数,是
XmlNamespaceManager类型,用于处理XML文档中的命名空间,当XML文档包含自定义命名空间时需要使用该参数。
基础使用示例
首先准备一个测试用的XML文档内容,保存为test.xml:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1">
<name>张三</name>
<age>20</age>
<score>95</score>
</student>
<student id="2">
<name>李四</name>
<age>21</age>
<score>88</score>
</student>
<student id="3">
<name>王五</name>
<age>20</age>
<score>92</score>
</student>
</students>
SelectSingleNode使用示例
下面的代码演示如何获取第一个student节点的name子节点内容:
using System.Xml;
class Program
{
static void Main()
{
// 加载XML文档
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("test.xml");
// 获取根节点
XmlNode root = xmlDoc.DocumentElement;
// 使用SelectSingleNode查询第一个student节点的name子节点
XmlNode? firstStudentNameNode = root.SelectSingleNode("student/name");
if (firstStudentNameNode != null)
{
Console.WriteLine("第一个学生的姓名:" + firstStudentNameNode.InnerText);
}
// 查询id为2的student节点
XmlNode? targetStudent = root.SelectSingleNode("student[@id='2']");
if (targetStudent != null)
{
XmlNode? ageNode = targetStudent.SelectSingleNode("age");
Console.WriteLine("id为2的学生年龄:" + ageNode?.InnerText);
}
}
}
SelectNodes使用示例
下面的代码演示如何获取所有年龄是20的学生节点,并遍历输出他们的姓名和分数:
using System.Xml;
class Program
{
static void Main()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("test.xml");
XmlNode root = xmlDoc.DocumentElement;
// 使用SelectNodes查询所有age节点内容为20的student节点
XmlNodeList? studentNodes = root.SelectNodes("student[age='20']");
if (studentNodes != null)
{
Console.WriteLine("年龄为20的学生信息:");
foreach (XmlNode student in studentNodes)
{
XmlNode? nameNode = student.SelectSingleNode("name");
XmlNode? scoreNode = student.SelectSingleNode("score");
Console.WriteLine($"姓名:{nameNode?.InnerText},分数:{scoreNode?.InnerText}");
}
}
// 获取所有score节点
XmlNodeList? allScoreNodes = root.SelectNodes("student/score");
if (allScoreNodes != null)
{
Console.WriteLine("所有学生分数:");
foreach (XmlNode scoreNode in allScoreNodes)
{
Console.WriteLine(scoreNode.InnerText);
}
}
}
}
带命名空间的使用场景
当XML文档包含自定义命名空间时,直接使用XPath查询会返回空结果,需要配合XmlNamespaceManager使用。比如下面的带命名空间的XML:
<?xml version="1.0" encoding="utf-8"?>
<ns:students xmlns:ns="http://www.ipipp.com/student">
<ns:student>
<ns:name>赵六</ns:name>
<ns:age>22</ns:age>
</ns:student>
</ns:students>
对应的查询代码需要添加命名空间管理:
using System.Xml;
class Program
{
static void Main()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("namespace_test.xml");
// 创建命名空间管理器
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
// 添加命名空间映射,前缀可以自定义,这里用ns对应原XML的ns前缀
nsmgr.AddNamespace("ns", "http://www.ipipp.com/student");
XmlNode root = xmlDoc.DocumentElement;
// 查询时XPath中的节点需要带上命名空间前缀
XmlNode? nameNode = root.SelectSingleNode("ns:student/ns:name", nsmgr);
if (nameNode != null)
{
Console.WriteLine("带命名空间的学生姓名:" + nameNode.InnerText);
}
XmlNodeList? studentNodes = root.SelectNodes("ns:student", nsmgr);
if (studentNodes != null)
{
Console.WriteLine("带命名空间的学生数量:" + studentNodes.Count);
}
}
}
常见使用注意事项
- 调用SelectSingleNode时如果查询不到结果会返回null,使用前需要判断非空,避免出现空引用异常。
- SelectNodes返回的集合是实时同步XML文档的,如果后续修改了XML文档,集合内容也会同步变化,不需要重新查询。
- XPath表达式的语法要符合规范,比如属性条件用@符号开头,层级关系用/分隔,错误表达式会导致查询失败。
- 如果XML文档很大,频繁使用复杂的XPath查询可能会影响性能,建议合理设计查询逻辑,减少不必要的查询操作。
注意:XPath表达式中的节点名称需要和XML文档中的节点名称完全一致,包括大小写,否则无法匹配到对应的节点。
C#SelectNodesSelectSingleNodeXmlNodeXML解析修改时间:2026-07-15 23:03:32