Having more-or-less painlessly migrated across to my SSD drive (which is more than can be said for the one I use at work, which randomly wiped itself – even down to the partition itself – after I moved desk last Friday), it’s back to VS2010 stuff. I had to do some work with XSD files … Continue reading Maintaining XSD files in VS2010
A Dynamic XML Document – Part 2
Continuing on from last post, how do we get the array-style [notation] on a dynamic object? Well, there’s a handy method that you can override on DynamicObject called TryGetIndex which does just that:
1: ///
Dynamic typing with C#4.0 part 2 – A Dynamic XML Document
Here’s a great example of where dynamic typing makes your code much more readable and logical: parsing an xml document. It turns out that someone has already done this – and I nicked a bit of his code (basically the implementation of IEnumerable) - but it’s funny how similar both of our code was before I found it (link is at end of this post).
Here’s an example XML document:
Gambardella, Matthew XML Developer's Guide Computer 44.95 2000-10-01 An in-depth look at creating applications with XML.
Now, to parse that document, you could currently use either good old XmlDocument (and / or XmlReader), or the more modern XDocument in Linq to Xml. However, both of them and still inherently weakly typed, using strings passed into methods such as “Attribute (“MyAttr”) or Element (“MyElement”). I did see an alpha demo of a strongly-typed version of a Xml Document reader a while ago but haven’t heard anything of that recently. I recall seeing that VB9 also has some good XML support, but I’m exclusively a C# coder so let’s concentrate on that 😉
Anyway. So let’s see if we can make an XML document class in C#4 which will let us read the above XML document like this:
1: // Create our dynamic XML document based off a Linq-to-Xml XElement. 2: var xDocument = XDocument.Load ("Example.xml"); 3: dynamic dynamicXmlDocument = new DynamicXmlDocument (xDocument.Root); 4: 5: // Get the first five books 6: var books = dynamicXmlDocument.book as IEnumerable; 7: foreach (dynamic book in books.Take (5)) 8: { 9: // Print out details on each book 10: System.Console.WriteLine ("Id: {0}, Title: {1}, Price: {2}", 11: book.id, // Attribute access 12: book.title.Value, // Element access 13: book.price.Value); // Element access 14: } 15: 16: // Get a specific book 17: var specificBook = dynamicXmlDocument.book["bk107"]; 18: System.Console.WriteLine ("Id: {0}, Title: {1}", specificBook.id, specificBook.title.Value); 19: 20: System.Console.Read ();
This actually wasn’t that difficult to write! Again, inheriting from DynamicObject and overriding a couple of methods, I was able to get this done in about three quarters of an hour.
First thing is the class hierarchy, our constructors and single member field:
1: class DynamicXmlDocument : DynamicObject, IEnumerable, IEnumerable 2: { 3: IEnumerable elements; 4: 5: ///