C#导入XML至DataGridView失败:SelectNodes无法读取节点求助
解决XML导入DataGridView时SelectNodes返回空的问题
嘿,我看你在把XML导入DataGridView时遇到了SelectNodes找不到节点的问题,这大概率是XML命名空间处理不当导致的,我帮你分析下问题并给出修复方案:
问题根源
你的XML文档里,<ImportEmployees>节点带有默认命名空间xmlns="http://m3as.com/SPDS",这意味着它下面的所有子节点(包括你要找的<Employee>)都属于这个命名空间。但你的代码里只添加了两个重复的http://www.w3.org/2001/XMLSchema-instance命名空间,完全没处理这个关键的默认命名空间,导致XPath查询找不到对应的节点。
修复后的完整代码
namespace DesktopApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { } private void openToolStripMenuItem_Click(object sender, EventArgs e) { int currRow = 0, currCell = 0; OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == DialogResult.OK) { string fileType = ofd.FileName; XmlDocument xDoc = new XmlDocument(); xDoc.Load(fileType); XmlNode root = xDoc.DocumentElement; // 关键:添加XML中的默认命名空间,给它一个前缀(比如spds) XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable); nsmgr.AddNamespace("spds", "http://m3as.com/SPDS"); // 保留i命名空间(如果后续需要用到带i前缀的节点) nsmgr.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance"); // 修正XPath:用前缀指定命名空间下的Employee节点 XmlNodeList listOfEmployees = root.SelectNodes("descendant::spds:Employee", nsmgr); foreach (XmlNode employee in listOfEmployees) { currCell = 0; // 每个员工的单元格索引要重置,避免越界 dataGridView1.Rows.Add(); // 先新增行,防止行索引不存在报错 foreach (XmlNode characteristic in employee) { // 更严谨的空值判断 if (!string.IsNullOrEmpty(characteristic.InnerText)) { dataGridView1.Rows[currRow].Cells[currCell].Value = characteristic.InnerText; } currCell++; } currRow++; } } } } }
额外的优化说明
- 重置单元格索引:每个
<Employee>节点遍历前要把currCell设为0,不然下一个员工的内容会从之前的单元格位置开始填充,导致索引越界 - 提前添加行:在给
Rows[currRow]赋值前先调用Rows.Add(),避免因为DataGridView中没有对应行而抛出索引错误 - 严谨的空值判断:用
!string.IsNullOrEmpty()替代简单的!= null,可以同时过滤空字符串和null的情况
为什么之前的代码找不到节点?
XML的默认命名空间(没有前缀的xmlns="...")会作用于所有子节点,XPath查询时必须通过命名空间管理器指定对应的前缀,否则会默认查找没有命名空间的<Employee>节点,自然匹配不到你XML里的节点。
内容的提问来源于stack exchange,提问作者dhh1097
相关产品推荐
相关产品推荐

