Take the 2-minute tour ×

I have a legacy HTTP/XML service that I need to interact with for various features in my application.

I have to create a wide range of request messages for the service, so to avoid a lot of magic strings littered around the code, I've decided to create xml XElement fragments to create a rudimentary DSL.

For example.

Instead of...

new XElement("root", 
  new XElement("request",
    new XElement("messageData", ...)));

I'm intended to use:

Root( Request( MessageData(...) ) );

With Root, Request and MessageData (of course, these are for illustrative purposes) defined as static methods which all do something similar to:

private static XElement Root(params object[] content) 
    return new XElement("root", content);

This gives me a pseudo functional composition style, which I like for this sort of task.

My ultimate question is really one of sanity / best practices, so it's probably too subjective, however I'd appreciate the opportunity to get some feedback regardless.

  1. I'm intending to move these private methods over to public static class, so that they are easily accessible for any class that wants to compose a message for the service.

  2. I'm also intending to have different features of the service have their messages created by specific message building classes, for improved maintainability.

Is this a good way to implement this simple DSL, or am I missing some special sauce that will let me do this better?

The thing that leads me to doubt, is the fact that as soon as I move these methods to another class I increase the length of these method calls (of course I do still retain the initial goal of removing the large volume magic strings.) Should I be more concerned about the size (loc) of the DSL language class, than I am about syntax brevity?


Note that in this instance the remote service poorly implemented, and doesn't conform to any general messaging standards, e.g. WSDL, SOAP, XML/RPC, WCF etc.

In those cases, it would obviously not be wise to create hand built messages.

In the rare cases where you do have to deal with a service like the one in question here, and it cannot be re-engineered for whatever reason, the answers below provide some possible ways of dealing with the situation.

share|improve this question
Depending on the XML, you might try hand-rolling C# types that serialize to the target XML. The attributes in the System.Xml.Serialization library are fairly adaptable if you're patient enough. It's a pain, but the resulting abstraction can be worth it if you have to use your hand-rolled proxy in a lot of places (e.g. in a unit test framework). –  Merlyn Morgan-Graham Sep 8 '11 at 3:56
add comment

4 Answers

Have you noticed that all the System.Linq.Xml classes are not sealed?

public class Root : XElement
    public Request Request { get { return this.Element("Request") as Request; } }

    public Response Response { get { return this.Element("Response") as Response; } }

    public bool IsRequest { get { return Request != null; } }

    /// <summary>
    /// Initializes a new instance of the <see cref="Root"/> class.
    /// </summary>
    public Root(RootChild child) : base("Root", child) { }

public abstract class RootChild : XElement { }
public class Request : RootChild { }
public class Response : RootChild { }

var doc = new Root(new Request());

Remember this won't work for 'reading' scenarios, you will only have the strong-typed graph from the XML that your application creates via code.

share|improve this answer
I like this option for creating this sort of xml, obviously if we the service had been built using some variety of XML/RPC/SOAP/WSDL (or some other useful standard,) this would mitigate the problem too. But when you're faced with a black box on the other end, this seems like the best way to deal with it. –  EmacsFodder Sep 8 '11 at 3:45
add comment

Hand-cranking xml is one of the things which should be automated if possible.

One of the ways of doing this is to grab the messaging XSD definitions off your endpoint and use them to generate C# types using the xsd.exe tool.

Then you can create a type and serialize it using the XmlSerializer, which will pump out your xml message for you.

share|improve this answer
Yes, it would be great if the endpoint did that, however it doesn't. This is a very basic XML/HTTP service, there is a single DTD that is used to describe the entire set of messages and responses, but aside from that there is nothing that would help with the definition of each explicit message and response type. –  EmacsFodder Sep 5 '11 at 23:11
add comment
up vote 1 down vote accepted

I noticed this article for constructing arbitrary XML with C#4.0 which is great.

The source for the library is here - https://github.com/mmonteleone/DynamicBuilder/tree/master/src/DynamicBuilder

At this time, there is a notable deficiency, no xml namespace support. Hopefully that will get fixed though.

As a quick example, here's how it's done.

dynamic x = new Xml();

Which yields:


Here's another quick example yanked from the article.

dynamic x = new Xml();

// passing an anonymous delegate creates a nested context
x.user(Xml.Fragment(u => {
    u.phone(new { type="cell" }, "(985) 555-1234");

Which yields:

    <phone type="cell">(985) 555-1234</phone>

Having used the Ruby library Builder this method of creating arbitrary XML is similarly terse, to the point that it verges on "fun"!

I've marked this as the answer, because, even though it doesn't directly speak to "using a DSL to create arbitrary XML" it tends to remove the need due to the extremely terse and dynamic nature of the syntax.

Personally I think this is the best way to create arbitrary XML in C# if you have the v4.0 compiler and have to crank it by hand, there are of course much better ways to generate XML automatically with serialization. Reserve this for XML which must be in a specific form for legacy systems only.

share|improve this answer
add comment

Writing this in C# seems an awful lot of work. Design your DSL as an XML vocabulary, and then compile it into XSLT, writing the compiler (translator) in XSLT. I've done this many times.

share|improve this answer
Can you go into more detail, or perhaps link to some materials that do? –  EmacsFodder Sep 5 '11 at 23:09
Sorry, don't have time (it would take time, it's a big question). And I don't really have enough information on your requirement to know where best to start –  Michael Kay Sep 6 '11 at 23:06
add comment

Your Answer


