将datagridview数据保存到xml

时间:2017-10-30 09:14:11

标签: c# xml datagridview

我已将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>

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

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”中的名称目前是我的列名,但是当用户保存文件时,它们必须是“name”。)

如何使用元素的属性保存XML?

1 个答案:

答案 0 :(得分: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);

        }
    }
}