简体   繁体   中英

XML file to DataGridView in C# asp.Net

This is the XML file I'm trying to fill the DataGridView with:

<?xml version="1.0" encoding="utf-8"?>
<Transactions>
<Transaction>
    <Name>David</Name>
    <Amount>123</Amount>
    <Date>11/11/2011</Date>
</Transaction>
<Transaction>
    <Name>Mark</Name>
    <Amount>400</Amount>
    <Date>12/12/2012</Date>
</Transaction>
<Transaction
    ><Name>Norah</Name>
    <Amount>400</Amount>
    <Date>12/12/2012</Date>
</Transaction>
<Transaction>
    <Name>Cecil</Name>
    <Amount>400</Amount>
    <Date>12/12/2012</Date>
</Transaction>

</Transactions>

This is the last code I tried, but it did not work.
Its C# asp.Net ( input array is more than number of columns I only have 3 columns (Name, Amount and Date)

DataTable dt = new DataTable();
XDocument doc = XDocument.Load(filepath);
foreach (XElement transactions in doc.Descendants().Where(x => x.Name.LocalName == "Transactions")){
    XElement Name = transactions.Descendants("Name").FirstOrDefault();
    XElement Amount = transactions.Descendants("Amount").FirstOrDefault();
    XElement date = transactions.Descendants("Date").FirstOrDefault();                
    dt.Rows.Add(new object[]
    {
        (string)Name.Element("Name"),
        (string)Amount.Element("Amount"),
        (string)date.Element("Date")
    });
}
dataGridView1.DataSource = dt;

There are a few problems with the posted code.

First, the “newly” created DataTable dt … is never given any columns. Therefore, it is not surprising to see the line of code… dt.Rows.Add(… crash and burn. Hence the current error. Adding the three lines of code below should solve this missing column error.

dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Amount", typeof(string));
dt.Columns.Add("Date", typeof(string));

Unfortunately fixing this issue will only reveal another problem…

The foreach loop is grabbing the XML “elements” improperly. I am guessing there is an easier way to do this however, using the posted XML file and taking a closer look at the foreach loop code below…

foreach (XElement transactions in doc.Descendants().Where(x => x.Name.LocalName == "Transactions")) { … }

I am guessing you want to change the string "Transactions" to "Transaction" without the “s.” Leaving the “s” in the string is going to pick up the “whole” XML file since "Transactions" is the root. Therefore, the code will need further clarification as “which” “Name, Amount or Date” to use since there is more than one (1). In addition, the loop will only execute “once” since it is grabbing the root node. I recommend changing the value to "Transaction" to get what you are looking for.

Lastly, the code appears to be overly complicating things when grabbing the XElement value. As discussed above, we now know that we need to change the looping XElement variable to “Transaction,” this will mean that each “element” we get in the loop will look like…

<Transaction>
    <Name>David</Name>
    <Amount>123</Amount>
    <Date>11/11/2011</Date>
</Transaction>

Therefore… if we have an XElement called transaction like above, then a simple assignment…

string Name = Transaction.Element("Name").Value

should return the value we are looking for. It appears unnecessary to create the extra XElement variables (Name, Amount and date). The needed XElement already exist and it is called “transaction.” Given this, the code below should work as expected.

foreach (XElement transaction in doc.Descendants().Where(x => x.Name.LocalName == "Transaction")) {
      dt.Rows.Add(transaction.Element("Name").Value, transaction.Element("Amount").Value, transaction.Element("Date").Value);
    }

With that said, the code below demonstrates what is described above.

try {
    DataTable dt = new DataTable();
    dt.Columns.Add("Name", typeof(string));
    dt.Columns.Add("Amount", typeof(string));
    dt.Columns.Add("Date", typeof(string));
    XDocument doc = XDocument.Load(filepath);
    foreach (XElement transaction in doc.Descendants().Where(x => x.Name.LocalName == "Transaction")) {
      dt.Rows.Add(transaction.Element("Name").Value, transaction.Element("Amount").Value, transaction.Element("Date").Value);
    }
    dataGridView1.DataSource = dt;
}
catch (Exception ex) {
  MessageBox.Show("Error: " + ex.Message);
}

It should also be noted that when the code uses the line below…

transaction.Element("NodeName").Value

If “NodeName” does not exist, there is NO exception thrown, it will simply return null. Therefore, if you see the correct number of rows but missing data, it would be wise to check what is returned when reading from the XElement . Hope that helps.

Try this code

  using System.Xml;

    XmlReader xmlFile = XmlReader.Create(@"C:\Users\Shubham\Documents\Visual Studio 2012\Projects\WindowsFormsApplication1\WindowsFormsApplication1\XMLFile1.xml", new XmlReaderSettings());
            DataSet dataSet = new DataSet();
            //Read xml to dataset
            dataSet.ReadXml(xmlFile);
            //Pass Transaction table to datagridview datasource
            dataGridView1.DataSource = dataSet.Tables["Transaction"];

            //Close xml reader

            xmlFile.Close();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM