Monday, November 10, 2008

More Xml Design Patterns

[This was originally posted at]


Last month I mentioned some tips for structuring xml, which could be seen as the start of primitive Xml Design Patterns. Here are three more ideas.


Strongly-typed nodes


Say you have a node, which can have several different groups of attributes. For example, you're making a test automation DSL, and you need to assert that various conditions are met. You may have a basic assert, a correct-page assert, and a text-search assert:

The schema for this becomes messy - you'll have one node (Assert) with all possible attributes. Your interpreter will need to infer which action to take based on the current attributes. Validating the xml file also becomes error-prone. It's doable, but messy. Compare that to this:

.Page pageName="myPage.aspx" />

.Text textToFind="EmpId123" isRegex="false" isCaseSensitive="false" />

This approach has essentially three nodes: Assert, Assert.Page, and Assert.Text. This effectively gives you "strongly-typed nodes". Your interpreter instantly knows which type of node, and therefore what action it expects and how to validate its attributes. Your schema becomes simpler because each node type has only the relevant attributes. This isn't always the best approach, but it can be a good one in certain cases.



Serializing complex objects to attribute strings


You can serialize almost any object to Xml, but the question is what is the best way to do it? For example, you could serialize an array as a bunch of nodes:







However, this is somewhat bloated. A more concise way is to serialize it to a string, and then store the results in an attribute:

You could serialize an array as a CSV list: "1,2,3".

You could serialize a name-value pair: "name1=value1;name2=value2" (this is what MSBuild does)

You could even have a mini DSL, like the Silverlight path expressions: "M 10,100 C 10,300 300,-200 300,100".


The main thing this approach requires is an easy way to serialize and deserialize the object to a string. If you've got that, then this technique becomes very reasonable.



Abstract complex objects to inner content


Silverlight uses Xaml markup to describe the UI. Xaml allows a lot of style markup.


You can create a simple ellipse, shading the entire thing a solid blue.

Fill="Blue" />

However, you can also give it a more advanced two-color gradient shade by abstracting the "Fill" markup to the inner nodes of the ellipse. Specifying a single attribute is great when you can serialize all the necessary info to a single string, else you can leverage the more-powerful inner xml nodes (per a Jesse Liberty tutorial).



This allows the best of both worlds - the single-line common case, and the more advanced case.

No comments:

Post a Comment