使用DataTable在Datagridview中保存XML文件,而无需将DataTable.Name添加到XML文件

时间:2016-06-29 16:35:53

标签: c# xml datagridview datatable

语言:C#

我想保存一个从DataTable加载到DataGridView中的XML文件。我知道为了使用.WriteXML(),我必须为DataTable命名。我的问题是当我这样做时,DataTable Name然后被用作我的XML文件内的每个元素的包装器。我不希望这种情况发生。我只想编辑XML文件的值并将其保持在相同的布局中。

这是我的代码放入DataTable和DataGridView的方式:

string pathOfXML = C:\\FIlePath;

DataTable dt = new DataTable("XML_Table");    

public void XML_Document()
{
  XML_FILE = XDocument.Load(pathOfXML);

  dt.Columns.Add("Name");
  dt.Columns.Add("Value");

  var rows = doc.Root.Descendants().Select(element => new
  {
   Name = element.Name,
   Value = element.Value,
  }); 

  rows.ToList().ForEach(i => dt.Rows.Add(i.Name, i.Value));

  dgv_XML.DataSource = dt;
}

然后我在FormLoad()中调用此方法,以便它可以填充DataGridView。

我尝试使用按钮点击事件保存XML更改,以下是代码:

 void btn_Save_Click(object sender, EventArgs e)
 {       
   dt.WriteXML(pathOfXML);

   Messagebox.Show("Save Successful!");
 } 

XML文件应如下所示(它非常基本):

<Root>
    <Element> Value </Element>
    <Element> Value </Element>
    <Element> Value </Element>
    <Element> Value </Element>
    <Element> Value </Element>
    <Element> Value </Element>
    <Element> Value </Element>
</Root>

每当我尝试保存它时,它就是这样的:

<Root>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
    <XML_Table>
       <Name> Element Name </Name>
       <Value> Element Value </Value>
    </XML_Table>
</Root>

这会编辑值并保存它们,但它会放置&#34; XML_Table&#34;围绕每个元素,我只想停止那个&#34; XML_Table&#34;从发生。

2 个答案:

答案 0 :(得分:0)

无需重新发明轮子。只需使用DataTable.WriteXmlDataTable.ReadXml方法分别进行写作和阅读。

你的最终目标是什么?

如果要减小文件大小,请将列映射设置为属性而不是元素。同时指定表的短名称。

var dt = new DataTable("dt"); // short table name

// mapping to attribute
dt.Columns.Add("Name").ColumnMapping = MappingType.Attribute;
dt.Columns.Add("Value").ColumnMapping = MappingType.Attribute;

dt.Rows.Add("name1", "value1");
dt.Rows.Add("name2", "value2");

dt.WriteXml("test.xml");

这将产生以下结果。

<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <dt Name="name1" Value="value1" />
  <dt Name="name2" Value="value2" />
</DocumentElement>

如您所见,结果非常紧凑。几乎与你想要的一致。

好吧,试试完整的示例代码。

public partial class Form1 : Form
{
    public Form1()
    {
        //InitializeComponent();
        path = "test.xml";

        dataGridView = new DataGridView { Parent = this, Dock = DockStyle.Top };
        buttonLoad = new Button { Parent = this, Top = 170, Text = "Load" };
        buttonSave = new Button { Parent = this, Top = 200, Text = "Save" };

        buttonLoad.Click += ButtonLoad_Click;
        buttonSave.Click += ButtonSave_Click;
    }

    DataGridView dataGridView;
    Button buttonSave;
    Button buttonLoad;

    string path;
    DataTable dataTable;
    DataSet dataSet;

    private void ButtonLoad_Click(object sender, EventArgs e)
    {
        dataSet = new DataSet("Root");

        if (File.Exists(path))
        {
            dataSet.ReadXml(path, XmlReadMode.InferSchema);
            dataTable = dataSet.Tables[0];
        }
        else
        {
            dataTable = new DataTable("dt");

            dataTable.Columns.Add("Name").ColumnMapping = MappingType.Attribute;
            dataTable.Columns.Add("Value").ColumnMapping = MappingType.Attribute;

            dataTable.Rows.Add("name1", "value1");
            dataTable.Rows.Add("name2", "value2");

            dataSet.Tables.Add(dataTable);
        }
        dataGridView.DataSource = dataTable;
    }

    private void ButtonSave_Click(object sender, EventArgs e)
    {
        if (dataSet != null)
            dataSet.WriteXml(path);
    }
}

答案 1 :(得分:0)

我最终创建了动态标签来保存元素和文本框以保存值。然后我创建了一个for循环,这样我就可以得到增量“i”。然后我在for循环中放置了一个foreach循环,这样我就可以遍历每个元素,并用数组现在保存的值替换这些元素中的值。

int lblpositionX = 17;
int lblpositionY = 39;
int increment = 0;
string[] arr1 = {};

foreach (XElement Name in XDocumentName.Root.Descendants())
{
   Label lbl = new Label();
   lbl.Text = Name.ToString();
   lbl.Name = Name.ToString();
   lbl.Location = new Point(lblpositionX, lblpositionY);
   lblpositionY += 25;

   TextBox txt = new TextBox();
   txt.Text = Name.Value.ToString();
   txt.Name = "XML_Text" + increment;
   txt.Location = new Point(txtpositionX, txtpositionY);
   txtpositionY += 25;

   pnl_XML.Controls.Add(lbl);
   pnl_XML.Controls.Add(txt);
}

private void btn_Save_Click(object sender, EventArgs e)
{
   var textboxes = pnl_XML.Controls.OfType<TextBox>().Select(Control => Control.Text);
   arr1 = textboxes.ToArray();
   int textBox = textboxes.Count();

   for (int i = 0; i < textBox; i++)
   {
      foreach (XElement Name in XDocumentName.Descendants())
      {
         Name.Value = arr[i];
         i++
      }
      XDocumentName.Save(pathofXML);
      return;
   }
}