在C#开发中,读取XML节点属性是一项基础但容易出错的操做。无论是解析配置文件、处理第三方接口报文,还是读取本地数据,我们常常需要从特定节点中提取如id、name、type这类附加信息。C#主流提供了两套XML处理模型:基于DOM的XmlDocument和基于LINQ的XDocument,两者获取属性的写法有所不同,但底层都遵循W3C的XML规范。
使用XmlDocument获取节点属性
XmlDocument是传统的DOM解析方式,它会把整个XML加载到内存中,适合文档不大且需要随机访问节点的场景。要获取属性,一般先用SelectSingleNode定位到目标节点,然后通过节点的Attributes集合或GetAttribute方法取值。如果节点路径写错或XML结构变动,SelectSingleNode会返回null,直接访问属性就会抛出空引用异常,因此实际代码里必须做判空。
下面示例展示如何从一段包含书的XML中读取第一本书的category属性。注意我们使用XmlNode的GetAttribute,这个方法在属性不存在时返回空字符串而不是异常,相对安全。如果要按命名空间查找,还需配合XmlNamespaceManager,否则带前缀的节点会选不到。
using System;
using System.Xml;
class Program
{
static void Main()
{
string xml = "<?xml version='1.0'?><catalog><book category='WEB'><title>C#入门</title></book></catalog>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNode bookNode = doc.SelectSingleNode("/catalog/book");
if (bookNode != null)
{
string category = bookNode.GetAttribute("category");
Console.WriteLine("分类为:" + category);
}
else
{
Console.WriteLine("未找到book节点");
}
}
}
这种写法的优点是兼容老框架(.NET 2.0即可用),并且对复杂XPath支持很好。缺点是内存占用偏高,且XPath字符串拼写出错时只有运行时才能发现。若你的应用只是简单读取几个属性,用后面的XDocument往往更简洁。
使用XDocument与LINQ获取属性
XDocument从.NET 3.5开始引入,它把XML看成可查询的对象树,结合LINQ to XML可以用函数式风格取值。获取属性时,先把元素转为XElement,调用Attribute("名称")得到XAttribute对象,再用.Value读取。和XmlDocument不同,XDocument对命名空间的处理更显式,需要用XNamespace声明,否则查不到元素。
下面的代码完成同样任务,但写法更现代。我们用Descendants直接找所有book元素,取第一个,再用Attribute读取。如果属性可能缺失,可先判null再取Value,或者用强制转换(如(string)e.Attribute("category"))在缺失时得到null而非报错。
using System;
using System.Linq;
using System.Xml.Linq;
class Program
{
static void Main()
{
string xml = "<?xml version='1.0'?><catalog><book category='WEB'><title> C#入门 </title></book></catalog>";
XDocument doc = XDocument.Parse(xml);
XElement firstBook = doc.Descendants("book").FirstOrDefault();
if (firstBook != null)
{
XAttribute attr = firstBook.Attribute("category");
string category = attr != null ? attr.Value : "未知";
Console.WriteLine("分类为:" + category);
}
}
}
XDocument的优势是代码短、可读性强,且LINQ延迟执行对大文件流式处理友好(配合ReadFrom)。不过在极老的项目里可能不支持,且对XPath依赖少,习惯XPath的人需要适应。两种方式本质都是把XML节点映射成对象,属性作为节点的元数据存在。
常见错误与规避
第一类常见错误是属性名大小写不符。XML规范中属性名是大小写敏感的,写category和Category会被当成两个不同属性。建议从源XML复制名称,或统一约定小写。第二类是命名空间遗漏,当根节点带xmlns时,必须用命名空间管理器或XNamespace,否则SelectSingleNode和Descendants都返回空。
第三类是空引用。无论哪种方式,节点或属性都可能不存在,直接点Value或GetAttribute前务必判空。对于频繁读取的配置,可封装一个安全获取方法,统一返回默认值。下表列出两种方案的关键差异:
| 方案 | 适用版本 | 属性读取方式 | 命名空间处理 |
|---|---|---|---|
| XmlDocument | .NET 2.0+ | GetAttribute / Attributes | XmlNamespaceManager |
| XDocument | .NET 3.5+ | Attribute().Value | XNamespace显式声明 |
掌握上述写法后,C#获取XML节点属性将变得稳定可控。建议新项目优先用XDocument,维护老代码时沿用XmlDocument,并始终对可能为空的节点做防御性判断。
C#XMLXmlDocument修改时间:2026-08-03 11:09:57