Xslt and.NET, sooo good

Xslt and .NET, sooo good

Today I was designing some reports based on NUnit output.  It's easy to forget how powerful XSLT can be when used in the right scenario, and add in the full power of .NET, you have a pretty slick little xml processor.  The only snag is that I always forget how to hook stuff up, so this post is more a reminder of how to do this, it's really simple.

The example is based on the following xml:

  
  
  
  

In the spirit of hello world examples which is all that this is, I want to just spin through the customers and call a .NET method during the transform that will say hello to whatever string it's given, in this case the name of each customer.

Here's the xslt I want to use:

  
  
    
      
      
        

Defining methods to use in an xslt is as easy as creating a class with whatever methods your xslt needs. So our extension object looks like this:

public class StringUtils{
  public string SayHello(string customerName){
    return String.Format("Hello {0}!", customerName);
  }
}

The StringUtils.SayHello method is straight forward. The key to making it available to an xslt is hooking it up during the transform using the System.Xml.Xsl.XsltArgumentList.  Here is the code that does the transform:

XmlReader reader = XmlReader.Create("customers.xml");
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("customers.xsl");
XsltArgumentList xslargs = new XsltArgumentList();
xslargs.AddExtensionObject("ext:StringUtils", new StringUtils());
using (Stream stream = new FileStream("customers.html", FileMode.Create)){
    xslt.Transform(reader, xslargs, stream);
}

I did this in notepad++ so there's no project file. Sometimes I like not using visual studio for little things, helps me remember better. Here's how to compile the files:

csc /out:Program.exe /t:exe /r:System.dll,System.Xml.dll Program.cs

The output of the transform, not surprisingly looks like this:

Hello Chris!
Hello Emmitt!
Hello Anja!
Hello Riley!
Download the files here

ActiveSnippets in CodeRush 4.0 Screencast

CodeSmith 4.0 introduces ActiveSnippets. They are basically an easy way to integrate custom templates into visual studio.  I decided to put together a quick screencast to show how cool the ActiveSnippets feature can be. 

I've had a need in the past to generate enums from the values in a database table.  Normally, I would run a CodeSmith template I wrote that does exactly this, however I would need to leave my editor window in visual studio by starting the CodeSmith explorer, use the mouse(eek) to locate the template, click and pick a target column to use for the names of the enum options, and then click and pick a target column to use for the values of the enum options.

That's a lot of clicking, which is annoying.  ActiveSnippets eliminates this use case.  Here is a template I'm using for the enums:







    public enum 
    {
        		
    }

public DataTable GetData(){
    string cmdtext = String.Format("select {0}, {1} from {2}", 
        TextColumn.Name, ValueColumn.Name, ValueColumn.Table.Name);
    DataTable result = new DataTable();
    string connstring = TextColumn.Table.Database.ConnectionString;
    using (SqlDataAdapter da = new SqlDataAdapter(cmdtext, connstring)){
        da.Fill(result);	
    }
    return result;
}
public string ExtractLetters(string input){
    string result = "";
    if (String.IsNullOrEmpty(input))
        return result;

for(int i=0;i<input.Length;i++){
    if (Char.IsLetter(input[i]))
    	result += input[i];
}
return result;

}

ActiveSnippets are configured through Visual Studio, and you need to set up the alias that will be used to kick off the template.  My template name is TableToEnum.cst so I made my alias, tte. 

My template needs two parameters, ValueColumn, the column in the table that will be used for the values of the enum options, and TextColumn, which is used for the text of each enum option.

If you ever forget the parameters for a template, you can type the alias in a code editor window, highlight the alias an hit CTRL+E, CTRL+R.  The usage for the template will be dumped to the output window which is very handy.  This is demonstrated during the first part of the screencast.

CodeRush comes in handy too, once the enums are created, CodeRush has a kind of refactoring that lets you move type to a file of the same name.

Here's the screencast, it's about 6.8 megs.

Desktop Manager PowerToy for XP

I've been reluctant to try out any desktop managers just because I'm used to alt+tab but this weekend I decided to try out the Desktop Manager that's one of the Microsoft PowerToys for Windows XP. So far I like it, instead of alt+tab though, now it's getting used to the windows key + 1/2/3/4 to switch between desktops.

Super Cool Thumbnail Javascript Tool

Today I was looking for a cool JavaScript thumbnail tool and came across a crazy awesome library, Highslide. I posted the demos, you can check them out here or just go to the site.

Loving the new color scheme

So I took the leap and went for a totally new color scheme. I used the one from Jeff Atwood's entry on the topic, and then used the Consolas font I saw over at Scott Hanselman's blog. Here's my scheme:

Prototype + EventSelectors = Just Good Stuff

Prototype and EventSelectors rock. They make adding simple tricks to web pages soooo easy. today I had a need to be able to display multiple DataGrids that contain some rows that are the common to more that one grid. What I needed was that when a user hovered over a column that contained a particular value, that row in the grid would be highlighted yellow, and that same row in any other grid would be highlighted as well.  Using EventSelectors I set up some rules that were fired anytime that that the the mouse hovers over a TD element.  The grids that I was displaying were showing tax ids(this is an internal app), so my rule also checked that the innerHTML length was exactly 9 before it could be triggered.  Here's a demo that shows basically what I came up with.  Simple and easy.  Here are the EventSelector rules I implement:

var rules = {
  'td:mouseover':function(el){
    if(el.innerHTML.length == 9){
      el.parentNode.style.backgroundColor = '#FF0';
      $$('td').each(function(td){
        if(td.innerHTML == el.innerHTML){
          td.parentNode.style.backgroundColor = '#FF0';
        }
      });
    }
  },
  'td:mouseout':function(el){
    el.parentNode.style.backgroundColor = '#FFF';
    $$('td').each(function(td){
      if(td.innerHTML == el.innerHTML){
        td.parentNode.style.backgroundColor = '#FFF';
      }
    });
  }
}
EventSelectors.start(rules);
 
Author: , 0000-00-00