Hemme's Blog

Stories from behind the keyboard

  • RSS
  • Twitter
  • Linkedin

X2ml (X to ML) is a library I’m writing in C# to ease and speed-up the emission of markup code (such as HTML or XML) in .Net projects. The idea behind X2ml is to combine standard strings (System.String) with ad-hoc operators (ATM /, * and %) in order to produce a visual layout representing the structure of the resulting markup. Moreover, the library shows also good performance, comparable if not better to Linq2Xml (don't tell anyone).

For instance, in order to produce this HTML snippet

<div id='main'>
<h1>Hello X2ml!</h1>
<p class='intro'>
This is vanilla HTML.

..you can use X2ml this way:

var x = X.X2ml;
var xExpression = x["div"] 
* "@id:main"
/ "h1" 
* "Hello X2ml!"
% "p" 
* "@class:intro"
* "This is vanilla HTML.";

var htmlString = xExpression.ToXmlString();

The library can also be used in combination with Linq, to produce elements from collections. Can you spot what the following code does? (Solution is here)

//Building documents from Linq expressions is easy! 
var x = X.X2ml; //X is the magic class
var q = x["html"] 
/ "body" 
/ "table" * "@align=center" // '@' means 'class'
/ from row in tableInRam
select x["tr"] 
/ "th" * row.Key // '/' creates a child; 
% "td" * row.Value.ToString(); // '%' creates siblings 
var xml = q.ToXmlString(); //This one makes the XML string 

As you can see, apart from the starting operand of the expression, which signals the root element of the XML, all the other operands are plain strings. Operators, special 1-char prefixes like “@” and the indexer do the magic.

While I’m writing this post I’m thinking I can push the syntax a step further, for instance introducing the “#” prefix (ATM it does NOT work), e.g:

/* Introducing the '#' prefix you could reach 
the same effect of "div" * "@id:main" with a simpler: */

"div" * "#main"  

/* The following mod will stretch the syntax even more, allowing the usage 
of special chars like '@' and '#' inside a tag string: */

"div#main"          // <div id='main'/>
"p@intro"           // <p class='intro'/> 
"div#menu@floating" //<div id='menu' class='floating'/>

The project is published on http://x2ml.codeplex.com. Any suggestion and testing effort are welcome!

No comments: