I haven’t dabbled much with any of the dynamic features available in the .NET Framework, but I recently came across this very handy technique of using ExpandoObject to iterate, and access, XML data a lot cleaner. Let’s use the following XML
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee>
<FirstName>Jason</FirstName>
</Employee>
<Employee>
<FirstName>Mark</FirstName>
</Employee>
</Employees>
Using an XDocument, we would need to write the following code to iterate through each employee
var doc = XDocument.Load("XmlFile1.xml");
foreach (var element in doc.Element("Employees").Elements("Employee"))
Console.WriteLine(element.Element("FirstName").Value;
This is how I, and I assume many other devs, have gone about accessing XML data inside an XDocument. So here’s a neater way – an extension method that will do the hard work for us
public static class ExpandoXml
{
public static dynamic AsExpando(this XDocument document)
{
return CreateExpando(document.Root);
}
private static dynamic CreateExpando(XElement element)
{
var result = new ExpandoObject() as IDictionary<string, object>;
if (element.Elements().Any(e => e.HasElements))
{
var list = new List<ExpandoObject>();
result.Add(element.Name.ToString(), list);
foreach (var childElement in element.Elements())
list.Add(CreateExpando(childElement));
}
else
{
foreach (var leafElement in element.Elements())
result.Add(leafElement.Name.ToString(), leafElement.Value);
}
return result;
}
}
Taking in an XDocument, the extension method will iterate through all the XElements, and each child element of those, building up a hierarchy of ExpandoObjects. This provides us the ability to access the XML like so
var doc = XDocument.Load("XmlFile1.xml").AsExpando();
foreach (var employee in doc.Employees)
Console.WriteLine(employee.FirstName);
That looks much better.