XML and Fluent Interfaces

I have posted several times in the past on Fluent Interfaces. I think about Fluent Interfaces much in the same way I think about recursive functions, that is they are not for everything, but when you find the situation that warrants them then they are a great fit. On the other hand when you try to use them for the wrong situations they are an awful fit.

In the past, I’ve found at various orgs that i am constantly creating an XmlUtils() class to handle the creation of documents in a more tighter syntax. Back in those days, I was unaware of Fluent Interfaces and how they could possibly tackle this problem

Well today I just came across Mark Resmussen’s sweet FI for defining an XmlDocument, and it looks like a great fit.

XML we are trying to create

<?xml version="1.0" encoding="utf-8"?>
<root>
    <result type="boolean">true</result>
</root>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Using System.Xml

XmlDocument xd = new XmlDocument();
xd.AppendChild(xd.CreateXmlDeclaration("1.0", "utf-8", ""));

XmlNode root = xd.CreateElement("root");
xd.AppendChild(root);

XmlNode result = xd.CreateElement("result");
result.InnerText = "true";

XmlAttribute type = xd.CreateAttribute("type");
type.Value = "boolean";

result.Attributes.Append(type);
root.AppendChild(result);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }New way using Mark’s FI

XmlOutput xo = new XmlOutput()
    .XmlDeclaration()
    .Node("root").Within()
        .Node("result").Attribute("type", "boolean").InnerText("true");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

ANY QUESTIONS?

This entry was posted in coding, Featured, fluent interface, misc. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://sergeyshishkin.spaces.live.com/blog/cns!9F19E53BA9C1D63F!215.entry Sergey Shishkin: Fluent XML Writer

    Pingback

  • http://www.tobinharris.com/blog Tobin Harris

    I like it! The fluent interface approach certainly simplifies XML building tasks I think, much faster and more readable than working directly with the object model.

    I think that c# adn VB.NET will continue evolve to allow even simpler and more understandable syntax. This RubyOnRails code looks pretty nice I think…

    xml.customers {
    xml.customer( :id=>01) {
    xml.name(“Fred”)
    xml.age( 21 )
    xml.description(“blah”)
    }
    }



    Fred
    21
    Blah

  • Jon

    Have you seen the XML thing Andres Noras did with VB? I think it is pretty cool: http://andersnoras.com/blogs/anoras/archive/2007/07/15/is-it-a-bird-is-it-a-plane-it-s-a-dsl.aspx

    Scroll down untill you find the xml builder stuff…

  • http://www.kenegozi.com/blog Ken Egozi
  • http://marcossilva.wordpress.com Marcos Silva Pereira

    Nice, but Steve post a more readable solution. I alread have done something like that using Java (sorry :-P):
    Document doc = document(“root”,
    node(“some”,
    node(“inner1″),
    node(“inner2″)
    ),
    node(“more”),
    node(“evenmore”,
    attribute(“name”, “John”),
    attribute(“age”, “28″)
    ));

  • http://www.eduardomiranda.net/blogs/dotnet/ Eduardo Miranda

    I’m 100% in favor of LINQ to Xml and XDocument API. It express the developer intention in a clear, readable way. In VB.Net it’s even better, I don’t use VB for a while, but after diving into the new XML features, I’m almost like VB again :)

  • http://www.codebetter.com/blogs/glenn.block/ gblock

    @Bil, my suggestion was a bit of tongue-and-cheek. I like extension methods, but it’s a double-edge sword.

  • http://weblogs.asp.net/bsimser Bil Simser

    @Glenn: Totally, extension methods help us get a way better FI that makes the code much more readable. I’m looking at something like this for dealing with the SharePoint OM now and going to really push the readability of dealing with it for setting up tests (much like the Fluent Fixtures project does). Stay tuned for that as I’m in monster blog-mode lately.

  • http://www.codebetter.com/blogs/glenn.block/ gblock

    @Bil, I see your point, though the interface can certainly be expanded. Also don’t forget about all the extensions tricks we can do :)

  • http://www.codebetter.com/blogs/glenn.block/ gblock

    @Rob, it’s similar but different. Actually if you follow the post there’s an example of using the XDocument syntax.

  • http://iqueryable.com/ Steve

    I’m partial to LINQ to XML :)

    var xml = new XDocument(
    new XDeclaration(“1.0″, “utf-8″, “yes”),
    new XElement(“root”,
    new XElement(“result”, new XAttribute(“type”, “boolean”), “true”)
    )
    );

  • ehaskins

    VB
    Dim XDocument = < ?xml version="1.0" encoding="utf-8"?>

    true

    ANY QUESTIONS?

  • http://www.sergiopereira.com/articles/xmlbuilder.html Sergio Pereira

    I think in a not too distant future, we will look back at these things and be less than proud of them. There’s something about fluent interfaces that just doesn’t feel right to me, and it’s not just lack of habit. Time will tell.

  • http://weblogs.asp.net/bsimser Bil Simser

    While this might be fluent in look, it’s not fluent in feel to me. I still need to know things like InnerText and attributes and nodes. I think the approach is interesting, but needs work to make it really friction-free (without making it like crazy like batshit XML embedded inside VB that I really don’t understand or ever want to write).

  • http://www.bluespire.com/blogs Rob

    Also, note that you can do something very similar to this with XDocument:
    http://msdn2.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx