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.