如何在WinForm DataGridView中显示XML文件的完整多行数据?
解决WinForm DataGridView无法显示多行XML数据的问题
我来帮你排查并解决这个问题,先看你的代码和XML内容,主要问题出在XML结构和DataSet合并表的逻辑错误上,下面分情况给出解决方案:
情况1:你可以修改XML文件的结构(推荐)
DataSet的ReadXml方法要求XML有一个统一的根节点来包裹所有数据行,否则每个<Item>会被识别为单独的DataTable,导致你只能看到第一行数据。
修改后的XML结构:
<Items> <Item> <GTIN>35715475984623</GTIN> <CustomerArticleIdLC>75681</CustomerArticleIdLC> <CustomerArticleIdSAP>70000505</CustomerArticleIdSAP> <ArticleName>VODA VODA</ArticleName> <Quantity>96</Quantity> <UOM>KOM</UOM> </Item> <Item> <GTIN>12345678901234</GTIN> <CustomerArticleIdLC>12345</CustomerArticleIdLC> <CustomerArticleIdSAP>70000506</CustomerArticleIdSAP> <ArticleName>TEST DRINK</ArticleName> <Quantity>48</Quantity> <UOM>KOM</UOM> </Item> </Items>
简化后的代码:
你之前的循环合并表逻辑是错误的,ds.Merge(ds.Tables[i])是把表合并到DataSet,而不是合并到第一个表,完全不需要这个循环。修改后的代码如下:
private void button1_Click(object sender, EventArgs e) { try { using (XmlReader xmlFile = XmlReader.Create("ORD_BS_734_1499_20180515_1318.xml", new XmlReaderSettings())) { DataSet ds = new DataSet(); ds.ReadXml(xmlFile); // 直接绑定Item表,用表名比索引更清晰 dataGridView1.AutoGenerateColumns = true; dataGridView1.DataSource = ds.Tables["Item"]; } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
注意:使用using语句自动释放XmlReader资源,避免内存泄漏。
情况2:你无法修改XML文件(只能处理无统一根节点的XML)
如果XML就是多个独立的<Item>节点没有根容器,你需要手动读取每个节点并添加到DataTable中:
示例代码:
private void button1_Click(object sender, EventArgs e) { try { // 先创建DataTable并定义对应列 DataTable dt = new DataTable("Item"); dt.Columns.Add("GTIN", typeof(string)); dt.Columns.Add("CustomerArticleIdLC", typeof(string)); dt.Columns.Add("CustomerArticleIdSAP", typeof(string)); dt.Columns.Add("ArticleName", typeof(string)); dt.Columns.Add("Quantity", typeof(int)); dt.Columns.Add("UOM", typeof(string)); // 读取XML中的所有Item节点 XmlDocument doc = new XmlDocument(); doc.Load("ORD_BS_734_1499_20180515_1318.xml"); XmlNodeList itemNodes = doc.SelectNodes("//Item"); // 遍历节点并添加到DataTable foreach (XmlNode node in itemNodes) { DataRow row = dt.NewRow(); row["GTIN"] = node["GTIN"].InnerText; row["CustomerArticleIdLC"] = node["CustomerArticleIdLC"].InnerText; row["CustomerArticleIdSAP"] = node["CustomerArticleIdSAP"].InnerText; row["ArticleName"] = node["ArticleName"].InnerText; row["Quantity"] = int.Parse(node["Quantity"].InnerText); row["UOM"] = node["UOM"].InnerText; dt.Rows.Add(row); } // 绑定到DataGridView dataGridView1.AutoGenerateColumns = true; dataGridView1.DataSource = dt; } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
为什么你的原代码不行?
- 你提供的XML只有单个
<Item>,所以本来就只能显示一行;如果是多个<Item>但无统一根节点,ds.ReadXml会为每个<Item>生成单独的DataTable,每个表仅一行数据。 - 你写的循环合并逻辑完全错误:
ds.Merge(ds.Tables[i])是把其他表合并到DataSet中,而非将多个表的行合并到同一个表,最后你只绑定了第一个表,自然看不到其他行数据。
内容的提问来源于stack exchange,提问作者M.Ur
相关产品推荐
相关产品推荐

