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

使用XPath遍历XML节点存储定罪代码的问题排查

问题原因分析与解决方案

常见错误原因

  • XPath查询未限定范围:如果每次查询conviction节点时,都是基于整个XML文档而非当前遍历的proposer/driver节点,就会反复获取文档中第一个conviction的code值,导致重复。
  • 变量赋值逻辑错误:比如循环中未正确获取当前节点的code值,而是一直复用之前的变量值,最终列表里存的都是同一个重复值。

典型错误代码示例

假设你的代码是类似这样的(核心错误点已标注):

List<string> convictionCodes = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load("yourFile.xml");

XmlNodeList proposers = doc.SelectNodes("//proposer");
foreach (XmlNode proposer in proposers)
{
    // ❌ 错误:未限定在当前proposer节点下,会取整个文档的第一个conviction
    string code = doc.SelectSingleNode("//conviction/@code").Value;
    convictionCodes.Add(code);
}

XmlNodeList drivers = doc.SelectNodes("//driver");
foreach (XmlNode driver in drivers)
{
    // ❌ 同样的错误,重复获取第一个conviction的code
    string code = doc.SelectSingleNode("//conviction/@code").Value;
    convictionCodes.Add(code);
}

// 输出结果自然会重复第一个值
Console.WriteLine($"DrivingConvictionCode1={convictionCodes[0]}");
Console.WriteLine($"DrivingConvictionCode2={convictionCodes[1]}");
Console.WriteLine($"DrivingConvictionCode3={convictionCodes[2]}");

解决方案

方案1:限定XPath查询范围到当前节点

遍历proposer/driver节点时,使用当前节点的SelectSingleNode方法,XPath以.开头,表示从当前节点开始查询子节点:

List<string> convictionCodes = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load("yourFile.xml");

// 处理proposer节点下的conviction
foreach (XmlNode proposer in doc.SelectNodes("//proposer"))
{
    XmlNode conviction = proposer.SelectSingleNode(".//conviction");
    if (conviction?.Attributes["code"] != null)
    {
        convictionCodes.Add(conviction.Attributes["code"].Value);
    }
}

// 处理driver节点下的conviction
foreach (XmlNode driver in doc.SelectNodes("//driver"))
{
    XmlNode conviction = driver.SelectSingleNode(".//conviction");
    if (conviction?.Attributes["code"] != null)
    {
        convictionCodes.Add(conviction.Attributes["code"].Value);
    }
}

// 输出期望结果
if (convictionCodes.Count >= 3)
{
    Console.WriteLine($"DrivingConvictionCode1={convictionCodes[0]}");
    Console.WriteLine($"DrivingConvictionCode2={convictionCodes[1]}");
    Console.WriteLine($"DrivingConvictionCode3={convictionCodes[2]}");
}

方案2:一次性查询所有符合条件的节点

用XPath的或逻辑,直接获取所有proposer和driver下的conviction的code属性,简化代码:

List<string> convictionCodes = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load("yourFile.xml");

// 一次性获取所有目标code属性节点
XmlNodeList codeNodes = doc.SelectNodes("//proposer//conviction/@code | //driver//conviction/@code");
foreach (XmlNode codeNode in codeNodes)
{
    convictionCodes.Add(codeNode.Value);
}

// 输出结果
if (convictionCodes.Count >= 3)
{
    Console.WriteLine($"DrivingConvictionCode1={convictionCodes[0]}");
    Console.WriteLine($"DrivingConvictionCode2={convictionCodes[1]}");
    Console.WriteLine($"DrivingConvictionCode3={convictionCodes[2]}");
}

方案3:使用LINQ to XML(更简洁可靠)

如果你的项目基于.NET Framework 3.5及以上,推荐使用LINQ to XML,代码更简洁且不易出错:

XDocument doc = XDocument.Load("yourFile.xml");
List<string> convictionCodes = doc.Descendants()
    .Where(node => node.Name == "proposer" || node.Name == "driver")
    .Descendants("conviction")
    .Select(conv => conv.Attribute("code")?.Value)
    .Where(code => !string.IsNullOrEmpty(code))
    .ToList();

// 输出结果
if (convictionCodes.Count >= 3)
{
    Console.WriteLine($"DrivingConvictionCode1={convictionCodes[0]}");
    Console.WriteLine($"DrivingConvictionCode2={convictionCodes[1]}");
    Console.WriteLine($"DrivingConvictionCode3={convictionCodes[2]}");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:16:36