September 23, 2005

XLinq Bitter Words, Part I - XML functional construction

XLinq is new and hot technology everybody seems to be happy with. I'm going to post a different review series - not what I like, but what I dislike and want to be fixed in XLinq. Sorry in advance for bitter words, but it's better when your friend says them ...

XML Tree functional construction is a great stuff and definitely a big improvement over the upside down DOM-style XML building. I only wanted to note that one doesn't have to wait years for C# 3.0 to be able to build XML tree in a natural top-down way, that was actually possible from the very beginning (here is .NET 2.0 sample, in .NET 1.X one would need XmlNodeWriter):

    XmlDocument doc = new XmlDocument();    
    XmlWriter w = doc.CreateNavigator().AppendChild();
    w.WriteStartElement("contacts");
      w.WriteStartElement("contact");
        w.WriteElementString("name", "Patrick Hines");
        w.WriteStartElement("phone");
          w.WriteAttributeString("type", "home");
          w.WriteString("206-555-0144");
        w.WriteEndElement();
        w.WriteStartElement("phone");
          w.WriteAttributeString("type", "work");
          w.WriteString("425-555-0145");
        w.WriteEndElement();
        w.WriteStartElement("address");
          w.WriteElementString("street1", "123 Main St");
          w.WriteElementString("city", "Mercer Island");
          w.WriteElementString("state", "WA");
          w.WriteElementString("postal", "68042");
        w.WriteEndElement();
      w.WriteEndElement();
    w.WriteEndElement();
    w.Close();
Should admit XLinq's functional construction still looks shorter and tree-friendly, but it is seriously constrained to building only XLinq XML tree in-memory. If one day you decide that building in-memory XML tree just to be saved to a disk is a waste of memory (and it is a waste), you would need to rewrite completely XML construction code and that's bad. XmlWriter has no limits here - you can use it for building XML tree in memory or writing XML directly to a stream in a fast efficicent non-caching way. XmlWriter just does its job - writes XML with no coupling to the result and that's way any code that produces XML with XmlWriter is more reusable.

Ergo - please don't repeat System.Xml mistakes and treat XmlWriter as a first class citizen - provide a way to build XDocument/XElement with XmlWriter, that will be good architecturally and will provide smoother migration from XmlDocument v2. E.g. what about providing an editable XPathNavigator over XElement or XDocument?

Update. And as a matter of interest XQuery being truly functional language of course supports functional composition too. Here is a sample:

element book { 
   attribute isbn {"isbn-0060229357" }, 
   element title { "Harold and the Purple Crayon"},
   element author { 
      element first { "Crockett" }, 
      element last {"Johnson" }
   }
}
Looks terribly familiar, huh?

But as Erik pointed out in comments neither form of composition can beat the ultimate way of building XML - literal one. Here is how it looks like in XQuery:

<example>
   <p> Here is a query. </p>
   <eg> $b/title </eg>
   <p> Here is the result of the query. </p>
   <eg>{ $b/title }</eg>
</example>
C# doesn't support it yet, while VB sort of does. "Sort of" because VB form of "literal XML" is not actually XML, but confusing ASP-like mess. But I'll address that later.

To be continued...