/// Tuesday, April 25

LCD Image Persistence

Most of us have long forgotten about CRT burn-in that plagued early monitors. Did you know LCDs have a similiar problem? It happened last night on my high-end 20" LCD. Image persistence results from displaying a static image on your screen for an extended period of time. In my case, it was a black color scheme for Windows. The icon and title 'persisted' on my screen. I usually work in maximized mode meaning the windows title bar for any application is at the top. I'm stumped, however, why my taskbar doesn't have the same symptoms. (I autohid it to check).

Fortunately this state is reversible in most cases. I am following Apple's advice since I need to use my computer:

Avoiding image persistence on Apple LCD displays

I went beyond the white background and switched to a Milk scheme for windows. I've noticed an improvement over night. There's still a slight hint of persistence which I hope will disappear in the next couple of days.

The other recommended solution is to shut off the LCD for several days. I'm not sure why this would be more effective than say shutting it off for one day. I'll try it if Apple's recommendation doesn't remedy the problem.

/// Saturday, April 15

XmlUnit

XMLUnit is a utility class to aid unit testing of XML processing. I've used it before but gave up on it too quickly mainly because it didn't ignore whitespace. I'm inundated with XML work. XMLUnit's differencing is too strict and is not very useful for me in its current state. So I downloaded the source, made it compliant with NUnit 2, modified a few unit tests so they run successfully from TestDriven.NET and finally added a property to ignore whitespace differences.

These two XML are now considered equal:

string control = "<a color=' red'><empty/>APPLE ORANGE</a>";
string test = "<a color=\"red\"><empty>        \t\r\n</empty>          APPLE   ORANGE          </a>";
XmlAssert.AreSimiliar(control, test);

Notice the library treats these as similiar (not identical):

I no longer have to worry about my xml editor reformatting my files and finding out later all my unit tests are broken. I'm considering starting a new project based on XMLUnit so I may enhance it and also rename methods to align it more closely with NUnit.

XSLT: How to autonumber all elements and attributes.

I'm doing more XSLT transformations and there's a lot of mapping to be done. I want to automate as much of the testing as I can. The first thing in order is how do I easily create a control sample so I can automate all attributes and fields mapped? Another stylsheet of course.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">
    
    <xsl:output indent="yes" encoding="utf-8"/>
    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="text()">
        <xsl:number level="any" format="0001" count="text()|@*"/>
    </xsl:template>
    
    <xsl:template match="@*">
        <xsl:attribute name="{name()}">
            <xsl:number level="any" format="0001" count="text()|@*"/>
        </xsl:attribute>
        
    </xsl:template>
        
    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

This simple stylesheet replaces the value of all attributes and elements with a sequential number from 0001 to n. The result looks like this.

<recipes>
    <recipe name="0001" prep_time="0002" cook_time="0003">
        <title>0004</title>
        <ingredient amount="0005" unit="0006">0007</ingredient>
        <ingredient amount="0008" unit="0009">0010</ingredient>
        <ingredient amount="0011" unit="0012" state="0013">0014</ingredient>
        <instructions>
            <step>0015</step>
            <step>0016</step>
            <step>0017</step>
        </instructions>
    </recipe>
</recipes>

This line needs a little explanation.

<xsl:number level="any" format="0001" count="text()|@*"/>

It says, create a counter for element text (text()) or attribute value (@*) encountered at any level, then format the number returning a four-digit number with leading zeros. The rest of the stylesheet is a modified identity template.

/// Thursday, April 13

XslTransform and xsl:document() woes

This little .NET feature consumed half my day (sarcasm intended). XslTransformation and document(''). .NET XSL transformations may behave unexpectedly when a stylesheet invokes the xsl:document() function. The same stylesheet results in two different outputs. If the stylesheet is loaded from a URI, such as a file, transformations produce expected results. Loading the stylesheet from a stream or a string, however, requires the workaround as described in the article above.

Why would one opt to load a stylesheet from a Stream or string? I prefer to embed test files and test stylesheets into an assembly by selecting the Embedded Resource action in Visual Studio. This is a neat trick if building with both NAnt and Visual Studio. Most NAnt projects build assemblies into a build, dist or bin directory. Visual Studio defaults to bin\debug and bin\release. An embedded resource always has the same path regardless where your assembly is located.

Loading a stylesheet from a non-URI location may reduce I/O as hinted in the article above. XSLT is ubiquitous. As sectors move towards standardization stylesheets become larger and larger. Most developers laboriously map one element to another. I treat XSLT as a cool programming language with a funky syntax. XML is structured and soon a resourceful developer realizes there's a pattern to the transformation. I tend to use lookup tables with the xsl:document() function. Resolving document('') to memory instead of a file reduces I/O.

I created a utility function to load stylesheets that use xsl:document().

XmlReader stylesheet = XmlUtils.LoadNonUriStylesheet(IOUtils.OpenEmbeddedResource("res/test.xls"));

LoadNonUriStylesheet loads the stylesheet assigning it an arbitrary URI. The URI is resolved by a custom resolver during transformation. OpenEmbeddedResource converts the res/test.xls path to a fully qualified namespace path then opens a Stream for the resource.

/// Tuesday, April 11

Test-Driven Development to the Rescue

My first project at my current job was to write some business rules against XML. At first, it seemed liked a daunting task. To write and test a rule required knowledge of the backend framework, the servers, many applications and patience to push a document through the framework. There was no way I could push through 420 test scenarios doing that. I spent several days analyzing what was in place to isolate my task, refactoring existing code etc (though i did not merge it back) to create a test harness. I even fibbed to the project manager on my progess knowing that I would make up the time later. That's how much confidence I have in Test-Driven Development. At first, things were slow-going. The pressure was mounting. Once I had my test harness in place, I'm guessing not only did I do this task faster than anyone before me, I also had reproduceable tests. To top of it, I had code generators to automate SQL scripting, etc. Testing was smooth as butter.

Thinking Dependency Injection

I'm creating components to convert proprietary source files into a standardized XML format. The legacy backend business components get their settings from disparate sources. Some settings are retrieved via a custom configuration object while others are read using stored procedures. Writing a unit test requires knowledge of how to retrieve those settings.

Point 1 - Components should be focused on business logic not infrastructure logic.

Here's a contrived example.

class XmlConverter {
    void Convert(int orderId)
    {
        // get settings from a database
        DbSettings dbSettings = GetDbMetadata(orderId);

        // get from config object
        string targetFile = OurConfig.GetPath("StandardStore") + dbSettings.OrderNumber + ".xml";
        
        string sourceXmlFile = dbSettings.XmlFile;
        string stylesheet = dbSettings.Stylesheet;
            
        string standardXml = XmlUtils.XslTransform(sourceXmlFile, stylesheet);
        
        using (TextWriter tw = new StreamWriter(targetFile))
        {
            tw.Write(standardXml);
        }
    }
}

The preceding code looks normal for most of us. And if you are the developer who wrote the code you know how to setup the database and you could select a valid order id so everything works when you test it. In addition, you know how the configuration object works and you can change its value blindfolded. It's so darn easy. Or is it?

Along comes poor me. I'm assigned to the project to fix an issue with the stylesheet. I hold a black-belt in stylesheet code-fu. Puh-leeze, I'll knock this task out in less than an hour. Then, why did it take me all day? Well because all that information you have in your head is too much to grasp for someone new to a project. The object knows too much. You know too much.

Point 2 - Objects should be a on a need-to-know basis.

How do we fix this with dependency injection? First, think backwards. Give the component the information it needs, instead of that component retrieving what it needs. That is the basic paradigm shift of Dependency Injection. A component is injected with the dependencies it needs. Let's rewrite this.

class XmlConverter {
    void Convert(string sourceXmlFile, string stylesheet, string targetFile)
    {
        string standardXml = XmlUtils.XslTransform(sourceXmlFile, stylesheet);
        
        using (TextWriter tw = new StreamWriter(targetFile))
        {
            tw.Write(standardXml);
        }
    }
}

Now the component is focused on what it has to do---converting a file and saving it to some known location. I can go in there and fix the stylesheet in 15 minutes and everyone is happy. What about configuration? First, let's look at the advantage of what just happened. To write a unit test, I simply pass in source XML file, a stylesheet file and the absolute path to where the transformed file is persisted. If everything works, I'm 99.9% sure my fix will close the ticket. I didn't have to know about infrastructure nor could I have affected it.

What about the settings? Someone has to retrieve it and inject it into the object. If you're the original coder, you would have already done this. If you're a maintainer, don't worry about it. You don't need to know to do your job. The infrastructure code is separate from business component logic. The application is easy to maintain.

Dependency Injection containers help in this effort by allowing you to wire objects together declaritively. For example, why build a SqlConnection object when you can ask the container for pre-built one?

SqlConnection connection = Container.GetObject("sqlconnection");

The container will cache it, or return a singleton or create a prototype when asked. Object instantiation is controlled declaritively either through a configuration file or a compiled script. The same kind of things you're doing now. Now it's done in one place and you don't have to build any infrastructure code. Use the container.

/// Sunday, April 9

Markdown vs. Markup

Today I stumbled upon Markdown.NET. I've been using my own homegrown text to HTML converter, MGutz.Markup, for a while now. I created a WinForms utility to convert text to HTML on-the-fly giving immediate feedback. I prefer the utility for the generation of plain HTML documents over DreamWeaver. I've changed the utility to support both Markdown and MGutz.Markup.

My disappointment with Markdown is it lacks markup for quick tables. MGutz.Markup supports nested tables as well as nested elements. Overall, Markdown has a cleaner syntax. MGutz.Markup's syntax tries to avoid escaping of characters used in code like '[', ']', '*', '_', '-' and '+'. As a consequence, MGutz.Markup source files are not as eye-friendly.I like Markdown and will probably use it for most day-to-day documents but I use tables a lot. I may change the grammar for MGutz.Markup since most of my code is usually eclosed in <pre></pre> blocks.

I have security concerns about Markdown. It's not suitable for use on Wiki's or CMS web sites as-is. It accepts raw HTML elements which could allow someone to insert javascript. MGutz.Markup, by default, does not allow the insertion of raw HTML elements. The escape sequence in MGutz.Markup tells the lexer to not evaluate the rule. Escaped tag sequences are still processed by HtmlEscape() . MGutz.Markup allows insertion of raw HTML tags only if a developer explicitly sets the EnableRawXml property. Likewise, links will not be generated unless EnableLinks is explicitly set.

Here's a quick comparison of the two:

html output

Markdown

MGutz.Markup

this is a para

HTML special chars: & < >

this is
  a
    para

HTML special chars: & < >
this is
  a
    para

HTML special chars: & < >

google

[google](http://www.google.com)

<<google, http://www.google.com>>

  • apple
  • orange
  • pear
- apple
- orange
- pear
// newline not requierd
@- apple 
@- orange 
@- pear
  1. one
  2. two
  3. three
1. one
2. two
3. three
@+ one @+ two @+ three
  1. one
    • apple
  2. two

?

@+ one @> @- apple @+ two

column heading

languages

right

C#, Boo

left

centered

sub-table

?

[[* column heading || languages ]]
[[> right || C#, Boo ]]
[[ left ||| centered [[sub-table]] ]]

bold italic code italic bold

_italic_ **bold** `code` _**italic bold**_

**bold** //italic// ::code:: //**italic bold**//

![alt text](http://buttons.blogger.com/bloggerbutton1.gif "Title")

@[http://buttons.blogger.com/bloggerbutton1.gif]

one two three

> one
> two
> three
@bq
one
two
three
bq@
/// Wednesday, April 5

Merging XML with XUpdate

I'm currently working on a backend process that receives two separate XML documents from different sources. The backend process must first transform each document, using XSLT, to conform to the company's standard format. The process then merges the two transformed documents into a single document. The merging operation requires some thought as the two documents share elements. Some elements are added while others are updated.

I wanted to automate this as much possible. The easy way out is to write some C# code and merge the documents using two XmlDocuments. But surely someone must have already thought of a better approach to this problem. My thought was to transform the first document like normal but transform the second document into an update document to be applied against the first document. The second document will contain embedded instructions on how to update the first.

After some googling, I found three solutions:

Microsoft XML Diff Language v.1.0 Beta

XUpdate Working Draft

Merging two XML Documents [using XSLT] by Oliver Becker

The Microsoft XML diff approach defines an XML diffgram language to describe the operations necessary to update a target document. It's not very readable using code numbers, etc for operations.

XUpdate follows a similiar approach defining basic commands and operations to update a target document. The language is much more readable and there exists several implementations for non-.NET languages. As a bonus I found a decent .NET implementation on Xinjie ZHANG's Homepage. The working draft, however, has not been touched for many years. I updated the DTD as well as the XUpdate class to support <xupdate:document-fragment/>.

Oliver Becker's approach is pure XSL. While I consider myself pretty darn good at XSL, XSL is just too much damn work. And trying to decipher someone else's XSL stylesheet takes at least three times the effort of trying to understand say C# code.

Here's an example using the XUpdate approach:

<!-- baseline.xml: target document -->
<recipes>
    <recipe name="unsalted bread" prep_time="5 mins" cook_time="3 hours">
        <title>Basic bread</title>
        <ingredient amount="3" unit="cups">Flour</ingredient>
        <ingredient amount="0.25" unit="ounce">Yeast</ingredient>
        <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient>
        <instructions>
            <step>Mix all ingredients together, and knead thoroughly.</step>
            <step>Cover with a cloth, and leave for one hour in warm room.</step>
            <step>Knead again, place in a tin, and then bake in the oven.</step>
        </instructions>
    </recipe>
</recipes>
<!-- diffgram.xml: contains an append and update command -->
<xupdate:modifications version="1.0" xmlns:xupdate="http://www.xmldb.org/xupdate">
    <!-- append the Salt ingredient -->
    <xupdate:append select="/recipes/recipe[@name='unsalted bread']">
        <xupdate:document-fragment>
            <ingredient amount="1" unit="teaspoon">Salt</ingredient>
        </xupdate:document-fragment>
    </xupdate:append>

    <!-- change the recipe name to 'Salted Bread' -->
    <xupdate:update select="/recipes/recipe[@name='unsalted bread']/@name">Salted Bread</xupdate:update>
</xupdate:modifications>
// unit test
XmlDocument baseline = new XmlDocument();
baseline.Load(IOUtils.OpenEmbeddedResource("Xml/res/baseline.xml"));

XmlDocument diffgram = new XmlDocument();
diffgram.Load(IOUtils.OpenEmbeddedResource("Xml/res/diffgram.xml"));

XUpdate update = new XUpdate(baseline, diffgram);
update.Execute();

<!-- result of XUpdate.Execute() -->
<recipes>
    <recipe name="Salted Bread" prep_time="5 mins" cook_time="3 hours">
        <title>Basic bread</title>
        <ingredient amount="3" unit="cups">Flour</ingredient>
        <ingredient amount="0.25" unit="ounce">Yeast</ingredient>
        <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient>
        <instructions>
            <step>Mix all ingredients together, and knead thoroughly.</step>
            <step>Cover with a cloth, and leave for one hour in warm room.</step>
            <step>Knead again, place in a tin, and then bake in the oven.</step>
        </instructions>
        <ingredient amount="1" unit="teaspoon">Salt</ingredient>
    </recipe>
</recipes>
/// Wednesday, March 29

MSDN: Stored Procedure Object Interface Layer

MSDN has an article on a stored procedure data layer using attributes.

Stored Procedure Object Interface Layer

As usual, the open source community has been doing this sort of thing for a while—iBATIS. It can handle both stored procedures and straight SQL. iBATIS is much more flexible. There are some codegen tools that will do the mappings for you.

iBATIS

This page is powered by Blogger. Isn't yours?