使用多个 XML 文件中的特定 XML 节点填充 datagridview
Posted
技术标签:
【中文标题】使用多个 XML 文件中的特定 XML 节点填充 datagridview【英文标题】:Fill a datagridview with specific XML node from several XML files 【发布时间】:2020-09-08 18:14:33 【问题描述】:我必须用来自多个 XML 文件的 3 个特定 XML 节点数据填充 datagridview。
这是一个例子:
<?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>
我需要这些获得 3 个标签 - <numero_nfse>
、<data_nfse>
、<cod_verificador_autenticidade>
- 并将它们加载到数据网格视图中。
但是,有更多的 XML 文件,具有相同的标签,我会同时将所有这些文件加载到 datagridview 中。
我编写了下面的代码,如您所见,它不起作用。
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];
澄清一下:我希望每个标签有一列。因此,我的 datagridview 将包含 3 列和与目录中的文件一样多的行。每个 XML 文件中只有一个 <retorno>
。
谁能帮帮我?
【问题讨论】:
请edit 分享您尝试加载的XML 的(简化)示例——即minimal reproducible example。GetElementsByTagName()
已弃用 BTW:建议您使用 XmlNode.SelectNodes
或 XmlNode.SelectSingleNode
方法而不是 GetElementsByTagName
方法。
最好使用 LINQ to XML。
您正在为每个文件使用DataSet
和一个DataTable
。那是你真正想做的吗?为每个 XML 文件使用具有 3 列和 1 行的单个 DataTable
不是更有意义吗?当您执行dgvDadosNota.DataSource = retorno.Tables[j];
时,您将覆盖以前的绑定,因此您当然只会看到一个结果。
我的目标是读取该目录中的每个 XML 文件,获取每个文件中的具体标签并将它们加载到 datagridview 中。
@AndréLuis - 每个文件一行,<numero_nfse>
、<data_nfse>
和 <cod_verificador_autenticidade>
各一列?或者每个文件中是否可以有多个<retorno>
标签?因为不能将整个DataSet
绑定到DataGridView
,所以只能绑定特定的DataTable
。见How to bind Dataset to DataGridView in windows application。
【参考方案1】:
您正在将多个 XML 文件加载到 DataSet
中,每个文件都有一个 DataTable
,但如 How to bind Dataset to DataGridView in windows application 中所述,您只能绑定一个 单个 DataTable
到DataGridView
。
由于每个文件中只有一个 <retorno>
节点,因此将文件加载到具有 3 列的 DataTable
是有意义的 - <numero_nfse>
、<data_nfse>
和 <cod_verificador_autenticidade>
各一列 - 和每个文件一行。
下面的代码就是这样做的:
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;
请注意,我已切换到 LINQ to XML API,它通常比旧的 XmlDocument
API 更易于使用。
演示小提琴here.
【讨论】:
以上是关于使用多个 XML 文件中的特定 XML 节点填充 datagridview的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法使用 XSLT 基于 XML 中的元素复制 XML 节点 n 次?