使用 linq to XML 将 xml 文件导入 datagridview。数据显示不正确

Importing xml file to datagridview using linq to XML. data not displaying correctly

我的 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();

我收到的错误是...

"Object reference not set to an instance of an object."

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

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   

数据集怎么样?

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];
        }
    }
}
​

您的代码存在的问题是:-

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 并获取它的值。