如何使用LINQ to XML获取指定父节点下的去重子节点标签名称列表
基于LINQ to XML提取指定父节点下唯一子节点标签名方案
需求说明
需要从已加载的XML文档中,提取用户指定父节点下所有不同的直接子节点标签名,生成字符串列表。要求不从根节点开始遍历,结果不包含父节点自身标签名,逻辑完全动态适配用户输入的任意父节点名称。
原有问题
之前找到的LINQ to XML实现从根节点开始遍历,会将父节点标签名也纳入结果,不符合需求,原有错误代码如下:
List<string> nodesNames = new List<string>(); XDocument xdoc1 = XDocument.Load(destinationPath); XElement root = xdoc1.Document.Root; foreach (var name in root.DescendantNodes().OfType<XElement>() .Select(x => x.Name).Distinct()) { if (!nodesNames.Contains(name.ToString())) nodesNames.Add(name.ToString()); }
可正常运行的System.Xml参考实现
List<string> nodesNames = new List<string>(); XmlDocument doc = new XmlDocument(); doc.Load(destinationPath); XmlNodeList elemList = doc.GetElementsByTagName(inputParentNode); for (int i = 0; i < elemList.Count; i++) { XmlNodeList cnList = (elemList[i].ChildNodes); for (int j = 0; j < cnList.Count; j++) { string name = cnList[j].Name; if (!nodesNames.Contains(name)) nodesNames.Add(name); } }
示例XML结构
<?xml version='1.0' encoding='UTF-8'?> <parentlist> <parent> <firstchild>someValue</firstchild> <secondchild>someValue</secondchild> </parent> <parent> <firstchild>someValue</firstchild> <secondchild>someValue</secondchild> <thirdchild>someValue</thirdchild> </parent> </parentlist>
结果对比
- 原有LINQ to XML代码输出:
["parent", "firstchild", "secondchild", "thirdchild"] - System.Xml版本输出(预期结果):
["firstchild", "secondchild", "thirdchild"]
修改后的LINQ to XML实现
List<string> nodesNames = new List<string>(); XDocument xdoc1 = XDocument.Load(destinationPath); // inputParentNode为用户传入的目标父节点名称 nodesNames = xdoc1.Descendants(inputParentNode) // 仅取父节点的直接子元素,完全对齐原ChildNodes的遍历逻辑 .Elements() // 无需命名空间时用Name.LocalName,需保留命名空间可替换为Name.ToString() .Select(x => x.Name.LocalName) .Distinct() .ToList();
逻辑说明
Descendants(inputParentNode)会直接查找文档中所有名称匹配用户输入的父节点,无需从根节点手动遍历Elements()方法仅获取当前节点的直接子元素,不会递归查询后代节点,和原System.Xml中ChildNodes逻辑完全对齐- 内置
Distinct()方法自动去重,无需手动判断列表是否已存在对应标签名,代码更简洁
内容的提问来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

