Есть несколько проблем с размещенным кодом.
Во-первых, вновь созданным DataTable
dt
… никогда не дается никаких столбцов.Поэтому неудивительно, что строка кода ... dt.Rows.Add(…
падает и горит.Отсюда и текущая ошибка.Добавление трех строк кода, приведенных ниже, должно решить эту отсутствующую ошибку столбца.
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Amount", typeof(string));
dt.Columns.Add("Date", typeof(string));
К сожалению, исправление этой проблемы покажет только другую проблему ...
Цикл foreach
захватывает XML-элементыНеправильноЯ предполагаю, что есть более простой способ сделать это, используя опубликованный XML-файл и более внимательно рассмотрев приведенный ниже код foreach
…
foreach (XElement transactions in doc.Descendants().Where(x => x.Name.LocalName == "Transactions")) { … }
Я предполагаю, что вы хотите изменить строку«Транзакции» в «Транзакции» без «s». Если оставить «s» в строке, будет выбран «целый» XML-файл, поскольку «Транзакции» - это корень.Следовательно, код будет нуждаться в дополнительном разъяснении как «какое» «Имя, Сумма или Дата», поскольку их более одного (1).Кроме того, цикл будет выполняться только «один раз», поскольку он захватывает корневой узел.Я рекомендую изменить значение на «Транзакция», чтобы получить то, что вы ищете.
Наконец, код, кажется, слишком усложняет вещи при получении значения XElement
.Как обсуждалось выше, теперь мы знаем, что нам нужно изменить переменную цикла XElement
на «Транзакция», это будет означать, что каждый «элемент», который мы получаем в цикле, будет выглядеть так: *
<Transaction>
<Name>David</Name>
<Amount>123</Amount>
<Date>11/11/2011</Date>
</Transaction>
Поэтому... если у нас есть XElement
с именем transaction
, как указано выше, то простое присваивание ...
string Name = Transaction.Element("Name").Value
должно вернуть искомое значение.Кажется ненужным создавать дополнительные XElement
переменные (Имя, Сумма и дата).Необходимый XElement
уже существует, и он называется «транзакция». Учитывая это, приведенный ниже код должен работать, как и ожидалось.
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);
}
С учетом вышесказанного, код ниже демонстрирует то, что описано выше.
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);
}
Следует также отметить, что когда код использует строку ниже…
transaction.Element("NodeName").Value
Если «NodeName» не существует, исключение НЕТ, оно просто вернетноль.Поэтому, если вы видите правильное количество строк, но отсутствуют данные, было бы целесообразно проверить, что возвращается при чтении из XElement
.Надеюсь, это поможет.