Reputation: 23
I have to fill a datagridview with 3 specifics XML nodes data from several XML files.
Here it´s an example:
<?xml version='1.0' encoding='iso-8859-1'?>
<retorno>
<mensagem>
<codigo>00001 - Sucesso</codigo>
</mensagem>
<alerta>
</alerta>
<numero_nfse>641</numero_nfse>
<serie_nfse>1</serie_nfse>
<data_nfse>08/09/2020</data_nfse>
<hora_nfse>12:16:10</hora_nfse>
<arquivo_gerador_nfse>688569.xml</arquivo_gerador_nfse>
<cod_verificador_autenticidade>03379569</cod_verificador_autenticidade>
</retorno>
I need these get 3 tags - <numero_nfse>
, <data_nfse>
, <cod_verificador_autenticidade>
- and load them into a datagridview.
However, there are more XML files, with the same tags and I would to load all of them at the same time into a datagridview.
I wrote the code bellow and as you can see, it´s not working.
string[] arquivos = Directory.GetFiles(@"D:\Documentos\retorno");
DataSet retorno = new DataSet();
for (int j = 0; j < arquivos.Length; j++)
{
FileInfo Xmls = new FileInfo(arquivos[j]);
string caminhoXmls = Convert.ToString(Xmls);
XmlDocument retornoXml = new XmlDocument();
retornoXml.Load(caminhoXmls);
XmlNodeList retornoTags = retornoXml.GetElementsByTagName("retorno");
foreach (XmlNode xn in retornoTags)
{
string XmlNumeroNfse = xn["numero_nfse"].InnerText;
string XmlDataNfse = xn["data_nfse"].InnerText;
string XmlHoraNfse = xn["hora_nfse"].InnerText;
string XmlCodigo = xn["cod_verificador_autenticidade"].InnerText;
}
retorno.ReadXml(caminhoXmls);
dgvDadosNota.DataSource = retorno.Tables[j];
}
To clarify: I want one column for each tag. So my datagridview would be with 3 columns and as many rows as there are files in the directory. There´s only one <retorno>
in each XML file.
Can anyone help me?
Upvotes: 1
Views: 182
Reputation: 117190
You are loading your multiple XML files into a DataSet
with one DataTable
for each file, but as explained in How to bind Dataset to DataGridView in windows application you can only bind a single DataTable
to a DataGridView
.
Since you have only one <retorno>
node in each file, it would make sense to load the files into a DataTable
with 3 columns - one each for <numero_nfse>
, <data_nfse>
, and <cod_verificador_autenticidade>
- and one row for each file.
The following code does this:
static DataTable CreateDataTableFromRetornoXML(IEnumerable<string> fileNames)
{
var columnNames = new []
{
"numero_nfse",
"data_nfse",
"cod_verificador_autenticidade",
};
var rootName = "retorno";
var table = new DataTable();
foreach (var name in columnNames)
table.Columns.Add(name, typeof(string));
foreach (var fileName in fileNames)
{
var row = table.NewRow();
var root = XElement.Load(fileName);
var retorno = root.DescendantsAndSelf(rootName).Single(); // There should be only one.
foreach (DataColumn column in table.Columns)
{
row[column] = retorno.Element(column.ColumnName)?.Value;
}
table.Rows.Add(row);
}
return table;
}
Note I have switch to the LINQ to XML API which is generally easier to work with than the old XmlDocument
API.
Demo fiddle here.
Upvotes: 1