You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XElement/XDocument及LINQ-to-XML查找重复属性值节点并获取行号?

使用LINQ-to-XML查找重复axs属性的myNode节点并获取行号

要解决这个问题,我们需要分两步走:首先识别出哪些axs属性值是重复的,然后结合XmlReader来获取每个节点的行号(因为LINQ-to-XML的XElement本身不存储行号信息,得借助XmlReader的位置跟踪能力)。

先来看你的示例XML:

<parentNode> 
  <c-node> 
    <myNode axs="p1">Anything goes</myNode> 
    <myNode axs="p2">Nothing <aa>is</aa> here</myNode> 
    <myNode axs="p1">Whatever it may be</myNode> 
    <myNode axs="p3">...</myNode> 
  </c-node> 
</parentNode>

步骤1:找出重复的axs属性值

先加载XML文档,通过LINQ统计每个axs值的出现次数,筛选出出现次数大于1的值:

// 加载XML文档
var doc = XDocument.Load("yourXmlFilePath.xml");

// 获取所有myNode节点的axs属性值,筛选出重复的那些
var duplicateAxsValues = doc.Descendants("myNode")
                            .Select(node => node.Attribute("axs")?.Value)
                            .Where(val => !string.IsNullOrEmpty(val))
                            .GroupBy(val => val)
                            .Where(group => group.Count() > 1)
                            .Select(group => group.Key)
                            .ToHashSet();

步骤2:获取带行号的myNode节点

由于XElement不记录行号,我们需要用XmlReader来读取XML——它实现了IXmlLineInfo接口,可以获取节点的行号。我们可以定义一个简单的类来存储节点和对应的行号:

// 用于存储节点和行号的辅助类
public class NodeWithLineNumber
{
    public XElement Node { get; set; }
    public int LineNumber { get; set; }
}

// 读取XML并收集每个myNode的行号信息
var nodesWithLineNumbers = new List<NodeWithLineNumber>();

using (var reader = XmlReader.Create("yourXmlFilePath.xml", new XmlReaderSettings { IgnoreWhitespace = false }))
{
    while (reader.Read())
    {
        // 只处理myNode元素节点
        if (reader.NodeType == XmlNodeType.Element && reader.Name == "myNode")
        {
            // 将当前节点转换为XElement
            var element = XElement.ReadFrom(reader) as XElement;
            // 获取行号(XmlReader实现了IXmlLineInfo)
            var lineNumber = ((IXmlLineInfo)reader).LineNumber;
            
            nodesWithLineNumbers.Add(new NodeWithLineNumber 
            { 
                Node = element, 
                LineNumber = lineNumber 
            });
        }
    }
}

注意:这里把XmlReaderSettings.IgnoreWhitespace设为false,是为了确保行号对应XML文件中的实际行位置,避免因忽略空白节点导致行号偏移。

步骤3:筛选出重复axs值的节点

最后,结合第一步得到的重复axs值列表,筛选出目标节点:

// 筛选出axs值属于重复列表的节点
var duplicateNodes = nodesWithLineNumbers
                    .Where(item => duplicateAxsValues.Contains(item.Node.Attribute("axs")?.Value))
                    .ToList();

// 输出结果示例
foreach (var item in duplicateNodes)
{
    Console.WriteLine($"行号: {item.LineNumber}, axs值: {item.Node.Attribute("axs").Value}, 节点内容: {item.Node.Value.Trim()}");
}

运行这段代码后,你会得到所有axs="p1"的myNode节点及其对应的行号,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Bumba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:24:31