The World’s Leading Microsoft .NET Magazine
   
 
timstall

Donate Today!

Search Box

 

Calendar

««Feb 2010»»
SMTWTFS
 
1
23456
78910111213
14151617181920
21222324252627
28

My RSS Feeds








Mailing List

Most Popular Tags

                                                           

More Xml Design Patterns

posted Tuesday, 11 November 2008
 

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:

<Assert expected="val1" actual="someVariable" />

<Assert pageName="myPage.aspx" />

<Assert textToFind="EmpId123" isRegex="false" isCaseSensitive="false" />

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:

<Assert expected="val1" actual="someVariable" />

<Assert.Page pageName="myPage.aspx" />

<Assert.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:

<MyObject other_attributes="...">

    <Array>

        <Value>12</Value>

        <Value>35.5</Value>

        <Value>40</Value>

        <Value>9</Value>

    </Array>

</MyObject>

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

<MyObject other_attributes="..." values="12, 35.5, 40, 9" />

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.

<Ellipse Width="75" Height="75" x:Name="e1" 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).

<Ellipse Width="75" Height="75" x:Name="e2" >
    <Ellipse.Fill>
      <RadialGradientBrush GradientOrigin="0.2,0.2" >
         <GradientStop Color="White" Offset="0.2"/>
         <GradientStop Color="Blue" Offset="1"/>
      </RadialGradientBrush>
   </Ellipse.Fill>
</Ellipse>

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

tags:  

links: digg this    technorati