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

C#中获取XML错误发生位置行号的问题

问题:无法通过LoadOptions.SetLineInfo获取XML元素行号

场景与XML示例

当XML中<Name>元素的Units属性与子元素<List>的Units属性值不一致时需要触发错误,但使用LoadOptions.SetLineInfo无法获取错误对应的行号。

示例XML:

<Planets> 
  <Planet> 
    <Name Units="days" Order="1">
      <Lists>
        <List Units="nights">list_ends_here</List>
      </Lists>
    </Name>
  </Planet>
</Planets>    

现有代码问题

用户加载XML的代码存在变量名不匹配问题,且未正确定位到出错的<List>元素来获取行号:

加载XML的代码(存在问题)

XDocument xdoc = XDocument.Load(file, LoadOptions.SetLineInfo);
IEnumerable<XElement> planets = xdoc.Root.Descendants("Name");
foreach (XElement category in categories) // 此处categories未定义,应为planets
{
    //获取元素行号 
    string lineNumber = ((IXmlLineInfo)category).HasLineInfo() ? ((IXmlLineInfo)category).LineNumber.ToString() : "-1";
}

解析XML的代码

foreach(XElement pl_name in planets)
{
    string Units = pl_name.Attribute("Units").Value;
    var units_on_list = pl_name.Descendants("Lists").Elements("List").Select(x => (string)x.Attribute("Units")).ToList();
}

解决方案

1. 修正变量名错误

将遍历的变量从categories改为planets,确保遍历的是正确的<Name>元素集合。

2. 针对出错的<List>元素获取行号

当检测到Units不匹配时,需要对每个<List>元素转换为IXmlLineInfo来获取行号,而非仅获取其父元素<Name>的行号。

完整修正代码

XDocument xdoc = XDocument.Load(file, LoadOptions.SetLineInfo);
IEnumerable<XElement> nameElements = xdoc.Root.Descendants("Name");

foreach (XElement nameElem in nameElements)
{
    string nameUnits = nameElem.Attribute("Units")?.Value;
    if (string.IsNullOrEmpty(nameUnits))
        continue;

    var listElements = nameElem.Descendants("Lists").Elements("List");
    foreach (XElement listElem in listElements)
    {
        string listUnits = listElem.Attribute("Units")?.Value;
        if (string.IsNullOrEmpty(listUnits))
            continue;

        // 检测Units不匹配
        if (!nameUnits.Equals(listUnits, StringComparison.OrdinalIgnoreCase))
        {
            // 获取List元素的行号
            if (listElem is IXmlLineInfo lineInfo && lineInfo.HasLineInfo())
            {
                string errorLine = lineInfo.LineNumber.ToString();
                // 触发错误处理,比如抛出异常或记录日志
                throw new InvalidOperationException($"Units不匹配,错误行号:{errorLine}");
            }
        }
    }
}

关键说明

  • 使用LoadOptions.SetLineInfo后,所有XElement、XAttribute对象都可转换为IXmlLineInfo,包括子元素<List>。
  • 必须定位到实际出错的元素(此处为<List>),才能获取准确的错误行号。
  • 加入空值判断避免空引用异常,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:40:29