Pete Wright's Radio Weblog
Musings on anything and everything, but mainly code!

 

 

18 December 2004
 

I think it was Steve McConnell that first made me aware of the chicken roasting metaphor. In the story, Great Grandma McConnell (presumably) lived in a fairly small house but managed a close knit family circle. Each Sunday the family would come around and she'd roast them up a chicken, with all the trimmings of course, and serve a sumptuous family lunch. It became tradition after a short while though that the women of the family would help her prepare the meal (we're talking a long time ago here, obviously before the male brain evolved to the point that cooking was a skill they could acquire).

Now, Grandma's oven was small, but with a large family she needed to roast a large chicken each week. More often than not, Grandma would find that the chicken would not fit in the oven on a single shelf, so she would teach the onlookers that part of her solution to the problem was to remove the chicken's legs and bake them in a separate tray. Over the years this became the "standard" way to do things in that family. To cook the chicken, you'd baste it, stuff it, remove the legs and put two trays in the oven. When she passed away and the next generation took over, the tradition continued, and so on, to the present day. When asked in recent years but a younger member of the family "Grandma, why don't we just put the whole chicken in our Mondo-Fan-Assisted-Roastamatic 3000", the current 'Grandma' sneered, patted junior on the head and said "Because this is how we've always done it.". Despite the fact that the modern ovens are large enough to take the whole chicken, the family tradition of cutting off the legs first and cooking them separately continued. It's a pretty inefficient use of the oven space in some ways, and certainly a task that's no longer necessary, but since that is how it's always been done, that is how it will continue to be done.

When I first came across the world of XML, a confusing world full of academics and tweed wearing people at the time, I was embroiled in my first Enterprise Java project. I learned about the two methods of working with XML (SAX and the DOM) one of which gave me a fast forward reading stream into the XML document, and one of which represented the entire XML tree in memory for me to navigate around. I spent a long time learning the various parsers and standards out there in order to read my XML documents, and from them populate objects in memory, and all was good, if a little slow, tedious and bug-prone. When JDOM came along I rejoiced in it's simplicity (for those of you that don't know JDOM, it's a much less "academic" way to browse an XML source) and adopted it with some gusto, shortening my code bases and generally having a whale of a time.

When I came across the XML toolkit for VB, and then later the .NET class library's support for XML, I applied what I knew to those new toolsets. I would work the same way though, creating my shell objects, opening the XML source, reading it node by node, and populating the properties of my shells until eventually I had all the data I needed in a handy object based form. I took the chicken roasting approach to XML development. "This is how I've always done it, I know it works, and so this is how I'll carry on doing it". It's amazing to me now that I ever worked that way, and more amazing still to see others doing the same.

The issue is that most people read an XML document to extract information which at some point gets put into fields and properties in objects. So, many of us write code - vast, lengthy tracts of unweildy code - to do just that. But, in .NET XML is an object. With .NET your XML documents really can be thought of a serialized objects. Everybody already talks about how cool it is that we can serialize to XML, but just how many people out there really do it? I've not seen many, and I've had the pleasure of working with some of the very best people in the industry. .NET's XMLSerializer will both read and write XML into objects. When writing, public fields and properties (including object's and arrays) get written out to the XML file as Elements. When reading, Elements populate identically named fields and properties of a specified class. However, you can change this default behaviour to allow pretty much any format of XML document to hydrate an object.

Take a look at this XML

<Customer>
    <Name>Harry Webb</Name>
    <Company>Webbs Wonder Widgets</Company>
</Customer>

This can easily be used to hyrdate a customer object. Take a look at the following code to see how

using System;

using System.IO;

using System.Xml.Serialization;

 

namespace XMLSerialize2

{

class Class1

{

[STAThread]

static void Main(string[] args)

{

FileStream stream = new FileStream("c:\\customer.xml", FileMode.Open );

XmlSerializer ser = new XmlSerializer( typeof (Customer) );

Customer myCustomer = (Customer) ser.Deserialize( stream );

}

}

public class Customer

{

public string Name;

public string Company;

}

}

Trivial isn't it. All the code does is open a stream to read in the XML, and then create an XMLSerializer passing in the type of object that we are going to want to work with. Finally, the object is created by asking the serializer to Deserialize, passing in the stream. You can reverse the process and write out to a file with a call to Serialize, passing in the customer object itself as the second argument.

What about if the XML get's more complex though. Take a look at this

<Customer ID="12331">

    <Name>Harry Webb</Name>

    <Company>Webbs Wonder Widgets</Company>

    <Orders>

        <Order Number="12332" PO="123123">

        <Product>The widget Mark 1</Product>

        <Price>123.22</Price>

        <Quantity>54234</Quantity>

    </Order>

    <Order Number="222" PO="1123">

        <Product>The widget Mark 2</Product>

        <Price>13.22</Price>

        <Quantity>4234</Quantity>

     </Order>

    <Order Number="444123" PO="1aww3">

        <Product>The widget Mark 3</Product>

        <Price>23.22</Price>

        <Quantity>534</Quantity>

    </Order>

  </Orders>

</Customer>

That's a little more complex isn't it. By attaching attributes to the destination classes though, reading this into an object hierarchy is still trivial

public class Customer
{
    [XmlAttribute]
    public int ID;
    public string Name;
    public string Company;
    [XmlArray("Orders")]
    public Order[] CustomerOrders;
}
public class Order
{
    [XmlAttribute("Number")]
    public int OrderNumber;
    [XmlAttribute("PO")]
    public string PurchaseOrderNumber;
 
    public string Product;
    public double Price;
    public int Quantity;
}

Where attributes are used in the original XML document, prefxing the field in the class with [XmlAttribute] tells the serializer to look for an attribute with the same name. You'll also notice that in some of the attributes I've actually specified the name of the original element in the XML document where I have used a different field name in the class. Arrays are also catered for with the [XmlArray] attribute, and again I've specified the actual parent element name in the original XML document.

Easy isn't it. I'm never going back to using System.XML after this revelation. Thanks to Keith Ballinger's excellent book Essential Web Services for the lead. There's a lot more information in that book on the other things you can do to radically change the structure of the written document, as well as how to read SOAP Encoded documents into classes. Fantastic stuff.

 


5:50:23 PM    comment []

Yes, it is 6:30 am. I've been up since 4am. And yes it is a Saturday. No, I'm not massively late with my book schedules (I'm actually ahead by some strange quirk of chapter combinations fortuitously shortcutting the deadlines I published a week ago). Yes, everyone in the house is absolutely fine.

Something exciting is happening in my life. I'll blog about it when the powers that be have had a chance to digest it, but yes it is exciting enough to drag me out of bed at 4am on a Saturday morning to code, write and blog.

 

 


6:32:13 AM    comment []

I've been trying hard not to write blog posts that just point people to another resource on the NET; there are plenty of other blogs out there from more worthy bloggers that do just that. But, if I come across something really cool I figure it's ok to break my rule.

I just came across a fantastic article on just what click-one deployment is, and how to use it in the Whidbey Beta and CTP. Check it out at MSDN here.

I also got an idea for a new book from reading this (no, it won't be a book on click-once deployment - that's just silly). I'll put it on my brains dusty fermenting shelf, where fresh ideas go to eventually turn into mush or mature with age (the ones that mature invariably turn into books, software or new motorized vehicles with the potential to kill me)

 

 


6:30:00 AM    comment []


Click here to visit the Radio UserLand website. © Copyright 2005 Pete Wright.
Last update: 04/01/2005; 11:55:25.
This theme is based on the SoundWaves (blue) Manila theme.
December 2004
Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Nov   Jan