【问题标题】:Importing xml file to datagridview using linq to XML. data not displaying correctly使用 linq to XML 将 xml 文件导入 datagridview。数据显示不正确
【发布时间】:2015-11-05 16:09:12
【问题描述】:

我的 XML 文件...

<?xml version="1.0" encoding="UTF-8"?>
<files>
        <file type="main">
<document>Report.pdf</document>
         <field name="Company">Northwind</field>
         <field name="Description">monthly report</field>
         <line>
               <field name="Description">Error</field>
               <field name="Type">4444</field>
         </line>
         <line>
               <field name="Description">Info</field>
               <field name="Type">4562</field>
         </line>
         <line>
               <field name="Description">Error</field>
               <field name="Type">2135</field>
         </line>
          <field name="Analyst">Bob</field>
          <field name="Manager">Steve</field>
          <field name="Dept">Finance</field>
          </file>
</files>

目前的我的代码...

XElement xdoc = XElement.Load(@"C:\xmltest\input.xml");

                var lines = from item in xdoc.Descendants("line")

                            select new
                            {
                                Description = item.Value,
                                Type = item.Value

                            };

                dataGridView1.DataSource = lines.ToArray();

这是我得到的结果...

我想要的结果是……

我认为可能有效的代码...

 XElement xdoc = XElement.Load(@"C:\xmltest\input.xml");

                var lines = from item in xdoc.Descendants("line")

                            select new
                            {
                                Description = item.Attribute("field").Value,
                                Type = item.Value

                            };

                dataGridView1.DataSource = lines.ToArray();

我收到的错误是...

“对象引用未设置为对象的实例。”

【问题讨论】:

    标签: c# xml linq linq-to-xml


    【解决方案1】:

    你的代码的问题是:-

    item.Attribute("field").Value  //this line
    

    只需查看您的第一个查询,它就会返回该结果,因为item 代表每个line 节点,其中存在相应的field 节点。比如说第一个item 将是:-

    <line>
      <field name="Description">Error</field>
      <field name="Type">4444</field>
    </line>
    

    等等……

    现在,在第二个查询中,当您说item.Attribute("field").Value 时,它会抛出Null reference exception,因为每个item 不包含属性field(如上所示),而是element。所以你应该改写item.Element("field")。但是,这仍然不会给您预期的结果,因为您想根据属性值Descriptionname 获取数据。您可以这样编写查询:-

    var lines = from item in xdoc.Descendants("line")
                let fields = item.Elements("field")
                select new
                    {
                       Description = (string)fields
                           .FirstOrDefault(n => (string)n.Attribute("name") == "Description"),
                       Type = (string)fields
                           .FirstOrDefault(n => (string)n.Attribute("name") == "Type"),
                    };
    

    说明:

    xdoc.Descendants("line") 将获取所有行节点,如上所示,现在我们需要在其中找到所有 fields 节点,因此我们将其存储在名为 fields 的变量中。最后,在投影时,我使用FirstOrDefault 方法获取第一个匹配的name 属性,其值为DescriptionType,并获取它的值。

    【讨论】:

    • 谢谢,效果很好,我明白现在发生了什么:)。
    【解决方案2】:

    您可以尝试像这样按属性过滤:

    XElement xdoc = XElement.Load(@"XMLFile1.xml");
    
    var lines = from item in xdoc.Descendants("line")
                select new
                {
                    Description = item.Elements("field").Where(e => (string)e.Attribute("name") == "Description").First().Value,
                    Type = item.Elements("field").Where(e => (string)e.Attribute("name") == "Type").First().Value
                };
    
    var array = lines.ToArray();
    
    foreach (var item in array)
    {
        Console.WriteLine($"{item.Description}\t{item.Type}");
    }
    

    它会产生以下结果:

    Error   4444
    Info    4562
    Error   2135   
    

    【讨论】:

      【解决方案3】:

      DataSet 怎么样?

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Windows.Forms;
      
      namespace WindowsFormsApplication1
      {
          public partial class Form1 : Form
          {
              const string FILENAME = @"\temp\test.xml";
              public Form1()
              {
                  InitializeComponent();
      
                  DataSet ds = new DataSet();
                  ds.ReadXml(FILENAME);
      
                  dataGridView1.DataSource = ds.Tables[1];
              }
          }
      }
      ​
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-04
        • 1970-01-01
        相关资源
        最近更新 更多