必须显式声明并使用XNamespace,元素名由命名空间与本地名共同构成;正确写法为XNamespace ns = "URI"; doc.Root.Elements(ns + "book");避免忽略命名空间或字符串拼接命名空间前缀。

在C#中使用LINQ to XML查询带命名空间的XML,关键在于**必须显式声明并使用XNamespace**,否则查询会返回空结果——这是最常见的坑。
正确声明和使用XNamespace
XML命名空间不是“可选修饰”,而是节点全名的一部分。LINQ to XML中,元素名 = 命名空间 + 本地名,二者缺一不可。
- 用 XNamespace ns = "http://example.com/ns" 声明命名空间对象
- 构造带命名空间的元素名时,写成 ns + "ElementName"(如
ns + "book") - 不能用字符串拼接(如
"{http://example.com/ns}book")或忽略命名空间直接查"book"
完整查询示例(含默认命名空间)
假设XML如下(含默认命名空间):
对应C#代码:
- XNamespace ns = "http://mycompany.com/library";
- XDocument doc = XDocument.Load("books.xml");
- var titles = doc.Root.Elements(ns + "book").Elements(ns + "title").Select(x => x.Value);
处理多个命名空间或前缀的情况
如果XML中定义了带前缀的命名空间(如 xmlns:ns1="http://a.com" xmlns:ns2="http://b.com"),处理方式相同:
- 为每个URI分别声明
XNamespace ns1 = "http://a.com"、XNamespace ns2 = "http://b.com" - 查询时仍用
ns1 + "Element"或ns2 + "Item" - 注意:XNamespace不关心原始前缀名(如ns1、ns2只是C#变量名),只认URI是否匹配
避免常见错误
- ❌ 直接用
doc.Descendants("book")—— 忽略命名空间,查不到 - ❌ 写成
doc.Descendants("{http://...}book")—— 虽然语法合法,但易出错且不可读,不推荐 - ❌ 在查询中混用命名空间和无命名空间元素(如父元素有命名空间,子元素没声明)—— 实际上子元素会继承默认命名空间,需统一处理
- ✅ 推荐:把XNamespace声明为常量(如
private static readonly XNamespace LibNs = "http://mycompany.com/library";),提升可读性和复用性









