C#操做XML的方法有不少,但我的认为最方便的莫过于Linq to XML了,特别是XElement的Descendants方法是我最经常使用的一个方法。测试
这个方法能够根据节点名(Name)找到当前调用的XElement结点下全部的子XElement节点。最近,在写一个程序时时,让我有些新的发现。spa
示例XML文件:调试
1 <?xml version="1.0" encoding="utf-8"?> 2 <Activity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com/test"> 3 <Name>1</Name> 4 <Activities> 5 <Activity> 6 <Name>2</Name> 7 </Activity> 8 <Activity> 9 <Name>3</Name> 10 </Activity> 11 </Activities> 12 </Activity>
这是一个关于Activity结点的树形结构,每一个Activity节点都有一个Name子节点。我尝试着使用下面的代码,打印出全部Activity节点的Name子节点的值。code
1 var rootElement = XElement.Load("test.xml"); 2 var nameNodes = rootElement.Descendants("Name"); 3 4 foreach (var nameNode in nameNodes) 5 { 6 Console.WriteLine(nameNode.Value); 7 } 8 9 Console.ReadKey();
可是结果倒是空,当时很让我吃惊,通过调试后,我才发现我略了一个地方。不知道你们注意没有,测试的XML文件的根节点是有Namespace的,调用Descendants方法的时候,即便子节点没有指定Namespace,也会被自动添加上,而XElement的Name属性,偏偏是由Namespace和节点名共同组成的。找到缘由了,解决方法也就有了,只要作些小改动就好。xml
将代码blog
1 var nameNodes = rootElement.Descendants("Name");
改为utf-8
1 var nameNodes = rootElement.Descendants(rootElement.Name.Namespace + "Name");
便可。再次运行,即可打印出全部的Name节点值。it