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

基于XML的特定LINEXXXDEF节点筛选XPath查询需求

解决方案:正确筛选LINEXXXDEF节点的XPath与C#实现

一、正确的XPath查询

直接用这条XPath就能精准匹配你需要的两类节点,不会误抓非紧邻的节点:

//LINEXXXDEF[ASCMPXXDEF] | //LINEXXXDEF[EXDSCXXDEF][preceding-sibling::LINEXXXDEF[1][ASCMPXXDEF]]

拆分解释:

  • //LINEXXXDEF[ASCMPXXDEF]:匹配所有包含ASCMPXXDEF子节点的LINEXXXDEF,对应第一类需求。
  • //LINEXXXDEF[EXDSCXXDEF][preceding-sibling::LINEXXXDEF[1][ASCMPXXDEF]]:只匹配两种条件同时满足的节点:自身带EXDSCXXDEF子节点,且紧挨着它的前一个兄弟节点是带ASCMPXXDEF的LINEXXXDEF。这里的[1]是关键,确保只看紧邻的前一个,而非任意前面的节点,彻底避免误匹配lineno=7这类不符合紧邻要求的节点。

二、C#代码处理方案

如果用C#处理,下面两种常用方式都能实现需求:

1. LINQ to XML(XDocument)写法

这种方式代码更简洁灵活,适合.NET Core/.NET 5+环境:

using System;
using System.Linq;
using System.Xml.Linq;

class XmlNodeFilter
{
    static void Main()
    {
        // 替换为你的XML文件路径或直接加载XML字符串
        XDocument xmlDoc = XDocument.Load("target.xml");
        
        // 筛选第一类节点:包含ASCMPXXDEF的LINEXXXDEF
        var firstCategory = xmlDoc.Descendants("LINEXXXDEF")
                                  .Where(node => node.Elements("ASCMPXXDEF").Any());
        
        // 筛选第二类节点:紧跟第一类节点之后,且包含EXDSCXXDEF的LINEXXXDEF
        var secondCategory = xmlDoc.Descendants("LINEXXXDEF")
                                   .Where(node => node.Elements("EXDSCXXDEF").Any()
                                               && node.PreviousNode is XElement prevLine
                                               && prevLine.Name == "LINEXXXDEF"
                                               && prevLine.Elements("ASCMPXXDEF").Any());
        
        // 合并两类结果
        var allMatchedNodes = firstCategory.Concat(secondCategory);
        
        // 示例:输出匹配节点的lineno属性
        foreach (var node in allMatchedNodes)
        {
            Console.WriteLine($"匹配节点 lineno: {node.Attribute("lineno")?.Value ?? "无"}");
        }
    }
}

2. 传统XmlDocument写法

适合维护旧项目时使用:

using System;
using System.Xml;

class XmlNodeFilter
{
    static void Main()
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load("target.xml");
        
        // 用之前的XPath直接筛选两类节点
        XmlNodeList matchedNodes = xmlDoc.SelectNodes("//LINEXXXDEF[ASCMPXXDEF] | //LINEXXXDEF[EXDSCXXDEF][preceding-sibling::LINEXXXDEF[1][ASCMPXXDEF]]");
        
        // 示例:遍历输出结果
        Console.WriteLine("匹配的节点:");
        foreach (XmlNode node in matchedNodes)
        {
            XmlAttribute linenoAttr = node.Attributes["lineno"];
            Console.WriteLine($"lineno: {linenoAttr?.Value ?? "无"}");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:52:22