I finally cracked it, the trick is to use recursion, here is the updated dynamic version:
using System.Windows.Forms;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Linq;
using System;
namespace DataGridViewXml
{
public partial class Form2 : Form
{
private string xmlpath = @"test.xml";
public Dictionary<string, int> dgvHeaders;
public BindingSource dgvSource;
public object[] dgvRow;
public Form2()
{
InitializeComponent();
this.Run();
}
public void Run()
{
dgvHeaders = new Dictionary<string, int>();
XElement xelement = XElement.Load(xmlpath);
GetHeaders(xelement);
foreach (var header in dgvHeaders)
{
Debug.Print(header.Key.PadRight(20) + header.Value);
dataGridView1.Columns.Add(header.Key, header.Key);
}
dgvRow = new object[dgvHeaders.Count];
RecurseElements(xelement);
}
private void GetHeaders(XElement xelement)
{
foreach (var objx in xelement.Elements())
{
if (objx.HasElements)
{
GetHeaders(objx);
}
else
{
string header = objx.Name.ToString();
if (!dgvHeaders.ContainsKey(header))
{
dgvHeaders.Add(header, dgvHeaders.Count);
}
}
}
}
private void RecurseElements(XElement xelement)
{
foreach (var objx in xelement.Elements())
{
if (objx.HasElements)
{
RecurseElements(objx);
}
else
{
string name = objx.Name.ToString();
Debug.Print(name + " = " + objx.Value.ToString());
int columnPos = 0;
dgvHeaders.TryGetValue(name, out columnPos);
if (columnPos >= 0)
{
dgvRow[columnPos] = objx.Value;
}
else
{
Debug.Print(name + " ************* NOT FOUND ***********");
}
if (name.Equals("chksum"))
{
dataGridView1.Rows.Add(dgvRow);
dgvRow = new object[dgvHeaders.Count];
Debug.Print("--------------------------------");
}
}
}
}
}
}