将datagridview数据保存到xml

Posted

技术标签:

【中文标题】将datagridview数据保存到xml【英文标题】:Save datagridview data to xml 【发布时间】:2017-10-30 09:14:10 【问题描述】:

我已将 xml 文件加载到 datagridview。在用户完成更改后,我必须将其保存在与加载文件完全相同的结构中。

每个文件可以包含多个 TimeSlots

<?xml version="1.0" encoding="iso-8859-1"?>
<ELO2BDE>
<TimeSlots>
    <TimeSlot>
        <StartTime xmlns="TEST:TEST">2017-10-10T00:00:00</StartTime>
        <EndTime xmlns="TEST:TEST">2017-10-10T03:00:00</EndTime>
        <WorkShift xmlns="TEST:TEST">Night Shift</WorkShift>
        <WorkShiftModel xmlns="TEST:TEST">Default</WorkShiftModel>
        <UtilizationCategory xmlns="TEST:TEST">Corrective Work</UtilizationCategory>
        <UtilizationCategoryDetail xmlns="TEST:TEST" />
        <Remarks xmlns="TEST:TEST" />
        <OperatorPerson xmlns="TEST:TEST">PERSON</OperatorPerson>
        <IsAutoGenerated xmlns="TEST:TEST">false</IsAutoGenerated>
        <UsedEquipmentTypes xmlns="TEST:TEST" />
        <NameValuePairs xmlns="TEST:TEST">
            <NameValuePair>
                <Name>Project Number</Name>
                <Value>qwer</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Project Sub Number</Name>
                <Value>456</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Project Fuel Sub Number</Name>
                <Value>456</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Result Series</Name>
                <Value>test</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Result</Name>
                <Value>435-dfg-345</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Version</Name>
                <Value>1</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Engine Running Time</Name>
                <Value>390.4911</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Cum Fuel Consumption</Name>
                <Value>0</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>P Comment</Name>
                <Value />
            </NameValuePair>
            <NameValuePair>
                <Name>Type of Test</Name>
                <Value>0</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Test Sequence Number</Name>
                <Value />
            </NameValuePair>
            <NameValuePair>
                <Name>P Operating Mode</Name>
                <Value>290</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>P_VER</Name>
                <Value>15</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Testrun ID</Name>
                <Value>436456745</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Fuel Type ID</Name>
                <Value>11</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Dyno Power</Name>
                <Value>687</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Indi Channels</Name>
                <Value>0</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Testbed Type</Name>
                <Value>1E+10</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>S_LOGTIM</Name>
                <Value>20171010124918</Value>
            </NameValuePair>
            <NameValuePair>
                <Name>Project TFMS</Name>
                <Value/>
            </NameValuePair>
        </NameValuePairs>
        <DataList xmlns="TEST:TEST">
            <Value>UUT</Value>
            <Value>Entire</Value>
            <Value>0115138</Value>
        </DataList>
    </TimeSlot>
</TimeSlots>
<LogbookName>NAS Logbook</LogbookName>

这就是我将文件保存到 xDocument 列表中的方式:(我的问题的解决方案)

DataTable dt = new DataTable();
if (FileDataset.Count > 0) 
    FileDataset.Clear();    

dt = (DataTable)dgvData.DataSource;

var filegroup = dt.AsEnumerable().GroupBy(x => x.Field<string>("Filename")).ToList();
if (filegroup.Count > 0) 
    foreach (var file in filegroup)        
        string root = "ELO2BDE";
        string xmlIdentification = string.Format("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><0><TimeSlots></TimeSlots><LogbookName></LogbookName></0>", root);
        string ElementLogbookName = string.Empty;
        string FileName = string.Empty;

    XDocument outputDoc = XDocument.Parse(xmlIdentification);
    XElement timeSlots = outputDoc.Descendants("TimeSlots").FirstOrDefault();
    XElement LogbookNameRoot = outputDoc.Descendants("LogbookName").FirstOrDefault();
    XNamespace nsattr = "urn:TEST:TEST:TEST:Public";

    var groups = file.AsEnumerable().GroupBy(x => new 
        Filename = x.Field<string>("FileName"),
        starttime = x.Field<DateTime>("StartTime"),
        endtime = x.Field<DateTime>("EndTime"),
        workShift = x.Field<string>("WorkShift"),
        workShiftModel = x.Field<string>("WorkShiftModel"),
        utilizationCategory = x.Field<string>("UtilizationCategory"),
        utilizationCategoryDetail = x.Field<string>("UtilizationCategoryDetail"),
        remarks = x.Field<string>("Remarks"),
        operationPerson = x.Field<string>("OperatorPerson"),
        isAutoGenerated = x.Field<Boolean>("IsAutoGenerated"),
        userEquipmentTypes = x.Field<string>("UsedEquipmentTypes"),
        logbookName = x.Field<string>("LogbookName")
    ).ToList();

    foreach (var group in groups) 
        XElement timeSlot = new XElement("TimeSlot");

        timeSlots.Add(timeSlot);
        timeSlot.Add(new XElement(nsattr + "StartTime", group.Key.starttime));
        timeSlot.Add(new XElement(nsattr + "EndTime", group.Key.endtime));
        timeSlot.Add(new XElement(nsattr + "WorkShift", group.Key.workShift));
        timeSlot.Add(new XElement(nsattr + "WorkShiftModel", group.Key.workShiftModel));
        timeSlot.Add(new XElement(nsattr + "UtilizationCategory", group.Key.utilizationCategory));
        timeSlot.Add(new XElement(nsattr + "UtilizationCategoryDetail", group.Key.utilizationCategoryDetail));
        timeSlot.Add(new XElement(nsattr + "Remarks", group.Key.remarks));
        timeSlot.Add(new XElement(nsattr + "OperatorPerson", group.Key.operationPerson));
        timeSlot.Add(new XElement(nsattr + "IsAutoGenerated", group.Key.isAutoGenerated));
        timeSlot.Add(new XElement(nsattr + "UsedEquipmentTypes", group.Key.userEquipmentTypes));
        timeSlot.Add(new XElement(nsattr + "NameValuePairs"));
        XElement nameValuePairs = timeSlot.Element(nsattr + "NameValuePairs");

        List<DataRow> NameValuePairs = group.ToList();
        for (int i = 13; i < NameValuePairs[0].Table.Columns.Count - 3; i++) 
            var value = NameValuePairs[0].ItemArray.GetValue(i);
            if (!String.IsNullOrEmpty(value.ToString()))
                nameValuePairs.Add(new XElement(nsattr + "NameValuePair", new object[] 
                new XElement(nsattr + "Name" , NameValuePairs[0].Table.Columns[i].ColumnName),
                //new XElement(nsattr + "Value", NameValuePairs[0].Table.Rows[0][i].ToString()),
                new XElement(nsattr + "Value", value),
            ));
        

        timeSlot.Add(new XElement(nsattr + "DataList"));
        XElement DataList = timeSlot.Element(nsattr + "DataList");
        for (int i = NameValuePairs[0].Table.Columns.Count - 3; i < NameValuePairs[0].Table.Columns.Count; i++) 
            var value = NameValuePairs[0].ItemArray.GetValue(i);
            DataList.Add(new XElement(nsattr + "Value", value));
            //DataList.Add(new XElement(nsattr + "Value", NameValuePairs[0].Table.Rows[0][i].ToString()));
        
        ElementLogbookName = group.Key.logbookName;
        FileName = group.Key.Filename;
    
    LogbookNameRoot.Add(ElementLogbookName);
    outputDoc.Add(new XComment("Editied file at: " + DateTime.Now + " from PC: " + System.Environment.MachineName + " and User: " + System.Environment.UserName + " "));

    FileDataset.Add(FileName, outputDoc);
   

我该怎么做?

“NameValuePair”中的名称目前是我的列名,但当用户保存文件时,它们必须是“名称”。)

如何保存带有元素属性的 XML?

【问题讨论】:

如果您的问题中的 XML 不是全部在一行中,那么提供帮助会容易得多。 我编辑了xml文件。 c# Save DataGridView to Xml file的可能重复 【参考方案1】:

试试下面的代码。我必须添加一个命名空间来解析 xml 并添加一个唯一的行,因此每个 NameValuePair 都在表的一行中

using System;
using System.Collections.Generic;
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;
using System.Xml;
using System.Xml.Linq;

namespace WindowsFormsApplication4

    public partial class Form1 : Form
    
        const string INPUT_FILENAME = @"c:\temp\test.xml";
        const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
        public Form1()
        
            InitializeComponent();

            DataTable dt = new DataTable();

            dt.Columns.Add("StartTime", typeof(DateTime));
            dt.Columns.Add("EndTime", typeof(DateTime));

            dt.Columns.Add("WorkShift", typeof(string));
            dt.Columns.Add("WorkShiftModel", typeof(string));
            dt.Columns.Add("UtilizationCategory", typeof(string));
            dt.Columns.Add("UtilizationCategoryDetail", typeof(string));
            dt.Columns.Add("Remarks", typeof(string));
            dt.Columns.Add("OperatorPerson", typeof(string));
            dt.Columns.Add("IsAutogenerated", typeof(Boolean));
            dt.Columns.Add("UsedEquipmentTypes", typeof(string));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Value", typeof(string));

            XDocument doc = XDocument.Load(INPUT_FILENAME);
            XNamespace ns = null;
            foreach (XElement timeSlot in doc.Descendants("TimeSlot"))
            
                foreach (XElement nameValuePair in timeSlot.Descendants().Where(x => x.Name.LocalName == "NameValuePair"))
                
                    DataRow newRow = dt.Rows.Add();

                    ns = nameValuePair.GetDefaultNamespace();
                    newRow["StartTime"] = (DateTime)timeSlot.Element(ns + "StartTime");
                    newRow["EndTime"] = (DateTime)timeSlot.Element(ns + "EndTime");

                    newRow["WorkShift"] = (string)timeSlot.Element(ns + "WorkShift");
                    newRow["WorkShiftModel"] = (string)timeSlot.Element(ns + "WorkShiftModel");
                    newRow["UtilizationCategory"] = (string)timeSlot.Element(ns + "UtilizationCategory");
                    newRow["UtilizationCategoryDetail"] = (string)timeSlot.Element(ns + "UtilizationCategoryDetail");
                    newRow["Remarks"] = (string)timeSlot.Element(ns + "Remarks");
                    newRow["OperatorPerson"] = (string)timeSlot.Element(ns + "OperatorPerson");
                    newRow["IsAutoGenerated"] = (Boolean)timeSlot.Element(ns + "IsAutoGenerated");
                    newRow["UsedEquipmentTypes"] = (string)timeSlot.Element(ns + "UsedEquipmentTypes");
                    newRow["Name"] = (string)nameValuePair.Element(ns + "Name");
                    newRow["Value"] = (string)nameValuePair.Element(ns + "Value");

                
            
            dataGridView1.DataSource = dt;

            string root = doc.Root.Name.LocalName;
            string xmlIdentification = string.Format("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><0><TimeSlots></TimeSlots></0>", root);

            XDocument outputDoc = XDocument.Parse(xmlIdentification);
            XElement timeSlots = outputDoc.Descendants("TimeSlots").FirstOrDefault();


            var groups = dt.AsEnumerable().GroupBy(x => new
            
                starttime = x.Field<DateTime>("StartTime"),
                endtime = x.Field<DateTime>("EndTime"),
                workShiftModel = x.Field<string>("WorkShiftModel"),
                utilizationCategory = x.Field<string>("UtilizationCategory"),
                utilizationCategoryDetail = x.Field<string>("UtilizationCategoryDetail"),
                remarks = x.Field<string>("Remarks"),
                operationPerson = x.Field<string>("OperatorPerson"),
                isAutoGenerated = x.Field<Boolean>("IsAutogenerated"),
                userEquipmentTypes = x.Field<string>("UsedEquipmentTypes")
            ).ToList();

            foreach (var group in groups)
            
                XElement timeSlot = new XElement("TimeSlot");


                timeSlots.Add(timeSlot);
                timeSlot.Add(new XElement("StartTime", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.starttime));
                timeSlot.Add(new XElement("EndTimeTime", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"),group.Key.endtime));
                timeSlot.Add(new XElement("WorkShiftModel", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.workShiftModel));
                timeSlot.Add(new XElement("UtilizationCategory", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.utilizationCategory));
                timeSlot.Add(new XElement("UtilizationCategoryDetail", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.utilizationCategoryDetail));
                timeSlot.Add(new XElement("Remarks", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.remarks));
                timeSlot.Add(new XElement("OperatorPerson", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.operationPerson));
                timeSlot.Add(new XElement("IsAutogenerated", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.isAutoGenerated));
                timeSlot.Add(new XElement("UsedEquipmentTypes", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"), group.Key.userEquipmentTypes));

                timeSlot.Add(new XElement("NameValuePairs"));

                XElement nameValuePairs = timeSlot.Element("NameValuePairs");

                foreach (DataRow row in group)
                
                    nameValuePairs.Add(new XElement("NameValuePair", new object[] 
                        new XElement("Name", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"),row.Field<string>("Name")),
                        new XElement("Value", new object[] new XAttribute(XNamespace.Xmlns + "TEST", "TEST"),row.Field<string>("Value")),
                    ));
                

            

            outputDoc.Save(OUTPUT_FILENAME);

        
    

【讨论】:

将数据加载到datagridview不再是问题,在用户进行一些更改后我需要帮助保存。 您是在使用我的代码还是其他数据视图。最好用更改更新 DataTable,然后保存 DataTable。 是的。 NameValuePairs 中的每个名称/值必须在另一列中。 IE。 Dyno Power687 Columname=Dyno Power / 低于 687。但在保存 XML 输出时必须像输入一样,将名称/值作为元素。 我添加了我使用的加载方法。您的方法很棒,但我得到一个异常“附加信息:列'名称'不属于表。”我明白,因为我没有“名称/值”列,但我该如何纠正这个问题? 将列添加到代码中:dt.Columns.Add("Name/Value", typeof(string));但是该表已经将 NAME 作为列。

以上是关于将datagridview数据保存到xml的主要内容,如果未能解决你的问题,请参考以下文章

将datagridview数据保存到xml

如何使用从 datagridview 检索到的 ID 将数据保存到数据库?

急!在datagridview中修改或增加数据,单击按钮能将写入的数据保存到数据库里?求C#源代码,谢谢交个朋友

如何实现c# winform DataGridView添加一行,添加数据后,保存到数据库?

将编辑从 DataGridView 保存到 Datatable

vb.net将datagridview中的数据保存到txt并加载