Blog Archives
Parse XML to Dynamic ExpandoObject C# .NET 4.0
Posted by Ronnie Diaz
The example below uses the LINQ to XML predecessor System.Xml.XmlDocument simply because I still prefer the regex parsing method. It can easily be adapted to use XDocument instead based on your preference. The end resulting output (IEnumerable) is the same.
code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.Dynamic; using System.Xml.Linq; namespace AIS.Common { public class DocParser : IDisposable { public enum DocTypes { Xml }; private XmlDocument Document { get; set; } //private XDocument Document { get; set; } private DocTypes DocType { get; set; } //constructor /// <summary> /// /// </summary> /// <param name="dt">type of document, currently only supports xml</param> /// <param name="f">filename and path</param> public DocParser(DocTypes dt, string fp) { try { switch (dt) { case DocTypes.Xml: DocType = DocTypes.Xml; Document = new XmlDocument(); Document.Load(fp); //Document = XDocument.Load(fp); break; default: throw new Exception("Constructor::invalid or unknown doc type specified"); } } catch (Exception ex) { throw new Exception("Constructor::Error with document load or doc type.",ex); } } public IEnumerable<dynamic> GetElements(string regex) { return XmlToExpandoObject(regex); } private IEnumerable<dynamic> XmlToExpandoObject(string regex) { dynamic eo = new ExpandoObject(); var dictionary = eo as IDictionary<string, object>; XmlNodeList xnl = Document.SelectNodes(regex); foreach (XmlNode xn in xnl) { foreach (XmlAttribute xa in xn.Attributes) { dictionary[xa.Name.ToString()] = xa.Value.Trim(); //TrySetAttr(xn.LocalName, xn); } yield return eo; } } } }
sample xml:
<?xml version="1.0" encoding="utf-8" ?> <robots> <robot id="1" age="5" /> <robot id="2" age="3" /> </people>
usage:
DocParser dp = new DocParser(DocParser.DocTypes.Xml, Server.MapPath("~/xmlfilename.xml")); //can also retrieve xml from external service, etc var robots = dp.GetElements("*/robot"); foreach (var r in robots) { Console.WriteLine("Robot id={0}, age={1}", r.id,r.age); //output. if this is web app you will likely do this differently }
References
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx