C#读取XML文档值异常及版本判断问题求助
解决XML版本遍历与版本判断问题
先聊聊你遇到的两个核心问题:只能获取第一个版本号和System.NullReferenceException异常,然后咱们一步步修复,再实现版本判断的逻辑。
问题根源分析
- 节点遍历逻辑混乱:原代码里的嵌套循环没有精准定位节点类型,比如
dipConfig.DocumentElement.ChildNodes会包含空白文本节点(XML里的换行、缩进),导致后续遍历出错,只能拿到第一个有效版本。 - 空引用未做判断:直接访问
Attributes["xxx"].InnerText时,如果属性不存在或者节点本身是文本节点,就会抛出空引用异常。 - 未区分有效节点:遍历
versionNode的子节点时,会把空白文本节点也算进去,导致错误访问不存在的path属性。
修复后的完整代码
XmlDocument dipConfig = new XmlDocument(); dipConfig.Load("DipConfig.xml"); // 精准获取<versions>节点,避免遍历到无关的文本节点 XmlNode versionsNode = dipConfig.DocumentElement.SelectSingleNode("versions"); if (versionsNode == null) { Console.WriteLine("未找到versions节点"); return; } // 遍历所有<version>节点 foreach (XmlNode versionNode in versionsNode.SelectNodes("version")) { // 安全获取版本号:先判断属性是否存在 XmlAttribute versionAttr = versionNode.Attributes["number"]; if (versionAttr == null) { Console.WriteLine("当前version节点缺少number属性"); continue; } string versionNumber = versionAttr.InnerText; Console.WriteLine($"当前版本:{versionNumber}"); // 安全获取location路径 XmlNode locationNode = versionNode.SelectSingleNode("location"); if (locationNode != null) { XmlAttribute pathAttr = locationNode.Attributes["path"]; if (pathAttr != null) { string locationPath = pathAttr.InnerText; Console.WriteLine($"存储路径:{locationPath}"); } } // 获取orderedfields的有效字段数(排除空白文本节点) XmlNode orderedFieldsNode = versionNode.SelectSingleNode("orderedfields"); if (orderedFieldsNode != null) { // 只统计元素节点(比如<type>、<field>)的数量 int fieldCount = orderedFieldsNode.ChildNodes.Cast<XmlNode>() .Count(n => n.NodeType == XmlNodeType.Element); // 版本判断逻辑:根据字段数确定目标目录 string targetDirectory = fieldCount switch { 26 => @"C:\Version 4", 23 => @"C:\Version 3", _ => @"C:\UnknownVersion" // 处理未知字段数的情况 }; Console.WriteLine($"目标存储目录:{targetDirectory}"); // 这里可以添加生成CSV并保存到targetDirectory的逻辑 } }
关键改进点说明
- 精准节点选择:用
SelectSingleNode和SelectNodes代替直接遍历ChildNodes,避免拿到无关的空白文本节点,确保只处理有效元素节点。 - 空值安全判断:所有属性、节点访问前都先判空,彻底避免
NullReferenceException。 - 字段数统计逻辑:通过筛选
XmlNodeType.Element类型的节点,排除XML里的空白文本节点,得到真实的字段数量。 - 版本判断与目录映射:用switch表达式清晰实现字段数到目标目录的映射,还预留了未知版本的处理分支。
内容的提问来源于stack exchange,提问作者theDoron1
相关产品推荐
相关产品推荐

