Linq to XML 如何简便筛选嵌套深度最高的XML元素
更简洁的实现方式
不需要手动写遍历维护临时变量,直接用LINQ链式调用就能把筛选、取最深元素的逻辑合并,代码更短也更易读。
写法1:排序取首项(最易读)
直接对筛选出的符合条件的元素按嵌套深度降序排序,取第一个结果即可,和你原有遍历逻辑的行为完全一致——同深度元素会保留最后遍历到的那个,匹配你原来用>=判断的逻辑。
var deepestJohn = my_list.Elements() // 直接用XAttribute的string显式转换做判断,属性不存在时转换结果为null,不用单独写判空逻辑 .Where(x => (string)x.Attribute("Name") == "John") .OrderByDescending(e => e.AncestorsAndSelf().Count()) .FirstOrDefault();
写法2:Aggregate聚合(性能和手写遍历一致)
如果元素量很大不想承担排序的O(nlogn)开销,可以用Aggregate做线性遍历聚合,时间复杂度和你手写foreach完全一致,同样不需要单独声明临时变量:
var deepestJohn = my_list.Elements() .Where(x => (string)x.Attribute("Name") == "John") .Aggregate( (maxElem: null as XElement, maxDepth: 0), (acc, current) => { var currentDepth = current.AncestorsAndSelf().Count(); return currentDepth >= acc.maxDepth ? (current, currentDepth) : acc; }, acc => acc.maxElem );
注意:如果你要匹配的是my_list下所有层级的Name为John的元素,而不是仅直接子节点,记得把开头的
Elements()换成Descendants(),前者只会返回直接子元素,后者会递归遍历所有后代节点,避免漏匹配深层元素。
内容的提问来源于stack exchange,提问作者yo3hcv
相关产品推荐
相关产品推荐

