如何更优解析Visual Studio测试播放列表XML的DisplayName属性值?
优化Visual Studio测试播放列表XML解析方案
我正在寻找更优的方法解析Visual Studio保存的测试播放列表XML文件,目标是提取所有Name属性为DisplayName的Property元素的Value属性值。
测试播放列表示例
<Playlist Version="2.0"> <Rule Name="Includes" Match="Any"> <Rule Match="All"> <Property Name="Solution" /> <Rule Match="Any"> <Rule Match="All"> <Property Name="Project" Value="MyProject" /> <Rule Match="Any"> <Rule Match="All"> <Property Name="Namespace" Value="MyProject" /> <Rule Match="Any"> <Rule Match="All"> <Property Name="Class" Value="TestArc" /> <Rule Match="Any"> <Rule Match="All"> <Property Name="TestWithNormalizedFullyQualifiedName" Value="MyProject.TestArc.Insert_Arc" /> <Rule Match="Any"> <Property Name="DisplayName" Value="Insert_Arc" /> </Rule> </Rule> <Rule Match="All"> <Property Name="TestWithNormalizedFullyQualifiedName" Value="MyProject.TestArc.Insert_Arc_For_Construction" /> <Rule Match="Any"> <Property Name="DisplayName" Value="Insert_Arc_For_Construction(True)" /> <Property Name="DisplayName" Value="Insert_Arc_For_Construction(False)" /> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Rule> </Playlist>
预期结果
- Insert_Arc
- Insert_Arc_For_Construction(True)
- Insert_Arc_For_Construction(False)
现有实现代码
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"vs-3-tests.playlist"); XmlNodeList nodeList = xmlDoc.SelectNodes("//Property"); int counter = 0; foreach (XmlElement elem in nodeList) { if (elem.HasAttributes) { if (elem.Attributes[0].Value == "DisplayName") { counter++; Console.WriteLine($"{counter} - {elem.Attributes[1].Value}"); } } }
改进建议与更优方案
1. 优化XPath表达式,精准筛选目标节点
现有代码先获取所有Property节点再逐一判断,效率较低。可以直接用XPath定位到符合条件的节点,减少不必要的遍历:
XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"vs-3-tests.playlist"); // 直接筛选Name属性为DisplayName的Property节点 XmlNodeList displayNameNodes = xmlDoc.SelectNodes("//Property[@Name='DisplayName']"); int counter = 0; foreach (XmlElement elem in displayNameNodes) { // 检查Value属性是否存在,避免空引用异常 if (elem.HasAttribute("Value")) { counter++; Console.WriteLine($"{counter} - {elem.GetAttribute("Value")}"); } }
2. 使用LINQ to XML(更简洁现代的方式)
LINQ to XML是.NET中更易用、更灵活的XML处理方式,代码可读性更高,也更符合现代C#编程风格:
using System.Xml.Linq; XDocument doc = XDocument.Load(@"vs-3-tests.playlist"); var displayNames = doc.Descendants("Property") .Where(p => p.Attribute("Name")?.Value == "DisplayName") .Select(p => p.Attribute("Value")?.Value) .Where(v => v != null); int counter = 0; foreach (var name in displayNames) { counter++; Console.WriteLine($"{counter} - {name}"); }
3. 现有代码的潜在问题修复
- 避免依赖属性顺序:现有代码通过
Attributes[0]和Attributes[1]判断属性,若XML中属性顺序变化(比如Value在Name前面),代码会直接出错。应改用属性名称获取,比如elem.GetAttribute("Name")。 - 增加空值检查:未判断
Value属性是否存在,若某个DisplayName节点没有Value,会引发空引用异常,必须增加属性存在性检查。
内容的提问来源于stack exchange,提问作者Mattias Johansson
相关产品推荐
相关产品推荐

