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
相关产品推荐
相关产品推荐

