Skip to content. | Skip to navigation

Personal tools


You are here: Home / weblog

Dominic Cronin's weblog

Muenchian groupings in XSLT

Posted by Dominic Cronin at May 13, 2007 08:35 PM |
Filed under:

On Friday, a colleage at work asked me how to do something in XSLT. After a minute or so humming and hah'ing I said I'd have to think about it for a while. As it turned out, it took most of the weekend. (OK - as a parent of 2 under-3s, the amount of free time in a weekend is limited, but still, this was a tricky problem.)

The source XML document was something like this:

        <Message ID="first" ">
            <Body>You can now find details of the blah blah blah</Body>
        <Message ID="second" >
            <Body>Flibble de dee</Body>


Of course, there were lot more messages, but the important point was that my colleague wanted to group the messages by month. That meant that any Message whose Date element's first six characters were the same should be displayed together, no matter where they came in the source document.


This turns out to be a non-trivial problem in XSLT, and has been explicitly addressed as a weakness by the people responsible for XSLT 2.0. Anyway - the following works in XSLT 1.1; it's based on the Meunchian grouping technique (aka Fu-Muench-u).



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="messages" match="/list/item/Message" use="substring(Date, 1,6)"/>
    <xsl:template match="/">
        <xsl:variable name="messagesWithUniqueMonth" 
	select="/list/item/Message[generate-id()=generate-id(key('messages', substring(Date,1,6)))]"/>
        <xsl:for-each select="$messagesWithUniqueMonth">
            <xsl:sort select="substring(Date,1,6)"/>
            <xsl:call-template name="doMonth">
                <xsl:with-param name="month">
                    <xsl:value-of select="substring(Date,1,6)"/>
    <xsl:template name="doMonth">
        <xsl:param name="month"/>
        <div month='{$month}'>
            <xsl:for-each select="key('messages', $month)">
               <xsl:sort select="Date"/>
                    <xsl:value-of select="Title"/><xsl:value-of select="Date"/>

I had wanted to do something less arcane. I tried various approaches beginning with a variable containing all the dates, and then refining it, but most of the time I ended up with a <xsl:for-each/> unable to consume a result fragment or some such. The Muenchian technique works, even if it is opaque, and nothing else I tried did. I think it's probably possible using a recursive template to create a delimited string of months, but this way is definitely getting added to my toolbox.


For what it's worth, I'll recommend that we don't do this at all. The XML being transformed is already generated programatically, and it should be simple enough to add a month field that will make life a lot simpler.

Agile Correctness

Posted by Dominic Cronin at May 02, 2007 07:35 PM |

In his post Getting annoyed at Agile Correctness, Sam Gentile blows off a little steam at the people who engage in religious zealotry regarding agile practices. This amused me rather, as I recently had an encounter in which it seemed I was being accused of not being "agile enough".


Me: There are some of these tasks that we definitely need to do first. They are pre-requisites for tasks that need to come later.

Person who shall remain nameless: So you need to know everything before we start? We're in a conception phase!

Me: No - I just said we'll need to do some things first, and then the things that depend on them.

PWSRN: So you need to know everything before we start?

Me: I don't recall any such words leaving my mouth. (While thinking: What part of "we'll need to do some things first" did you manage to mis-translate?)

Whatever! It took a little longer to get there... I guess some people just can't metabolise clue.


A few days later, I got back from a short break to find that they'd arbitrarily switched the first and second elbonation phases, failing to note that this broke at least one dependency. Ho hum.

Separated at Birth?

Posted by Dominic Cronin at Apr 25, 2007 01:00 PM |

I know it must be hard to make a favicon (the icon that most browsers will display just to the left of the URL in the address bar), but simply picking a letter and adding bad typography might not be enough. What about these two?


I think we should be told.


BTW - If you get bothered by questions from your browser at this point, it's not my fault. Microsoft can't be bothered to use a certificate that joins up with the certificate authorities that Windows trusts. Doh!

Smashing the distraction stack for fun and profit

Posted by Dominic Cronin at Apr 01, 2007 06:20 PM |

In a recent post, Ned Batchelder, said "I was already three or four levels deep on the distraction stack, so I went and looked." This phrase fascinated me. Those of us who write software, or work with other complex technical tasks, often have to solve problems on several levels simultaneously, and I have long thought of this process as being similar to the way functions are called in software programmes.

Each function in a programme is dedicated to performing some task, but it may well need to call other functions to do this. The computer can only deal with one function at once, so it first needs to save the details of the calling function before beginning to process the function that is being called. The usual way of doing this is in a data structure called a stack. (In other contexts, this kind of structure might be referred to as a last-in-first-out queue, or a LIFO.) If the called function needs to call another function, it too "pushes its state" onto the stack before making the call. As each of the called functions finishes processing and returns, the state of the function that called it can be retreived, and that function can carry on where it left off. When that function in turn completes, its state in turn is sitting on the top of the stack waiting for retreival.

When researching a new technique, or finding the solution to a problem, this is often what you do. You get to a point where you can't carry on your current line of research without first solving some other problem. At this point, you make a mental note of where you are up to, and go off to solve the problem, repeating as necessary, and hoping that you don't have to hold mental state for too many things. As you solve each of the secondary problems, you back up to the point at which you got stuck, and at which you are now presumably not stuck any more.

Of course, it's not just when solving problems (in which case you pretty much have to follow this through to the bitter end). Sometimes, you are studying, and you find something that you should understand before moving on. This can lead to the same process of parking your mental state and taking some detour. There is often a choice as to whether you should do this now (stack-based processing) or queue the problem elsewhere for off-line processing. Whether you do this will generally depend on why you're doing what you're doing at the time. In Ned's case, he decided to indulge himself and go and check up an arcane detail of the HTML specification. Under other circumstances, you might have to carry on in the interests of progress and deny yourself the satisfaction of full knowledge.

From now on, when I'm busy with private-time research projects, and free to enjoy the diversions, I'll revel in the notion that I'm somewhere in the distraction stack.

Bare-behind programming in ASP.NET

Posted by Dominic Cronin at Mar 18, 2007 02:35 PM |

When is a Parser Error not a Parser Error?

..... when it's a BadImageFormatException, of course.

So what's he raving on about now, you may well ask? Well nothing much except an error that cropped up today when I was fiddling around with ASP.NET. Since I got my MCAD certification a couple of days ago, I've decided to take a break from the exam track for ju-u-u-st long enough to get some sanity back on the geekery front. As I'm now fully qualified to tell the world that I'm an ASP.NET expert ;-) I figured I'd spend a little time just screwing with stuff and generally trying to break things. Following my nose, if you like.... The good old fashioned way.

So there I was trying to figure out what the complete bare-ass minimum ASP.NET application would look like, partly with a view to figuring out what sort of technique to follow when developing stuff to port over to my mono server. Interesting enough. Coded up a page:

<%@Page Language="C#" Inherits="Minimal" CodeBehind="Minimal.aspx.cs%>
<html><head><title>Minimal ASP.NET page</title></head>
<body><asp:Literal>Hello, World!</asp:Literal></body>

The code behind file just has:

public class Minimal : System.Web.UI.Page {}

Hit F5 to run in Visual Studio. KAPOW! I'm a coding genius! It works! Up pops the browser with "Hello, World!" Great!

Ummm - hang on a second. View Source.... Phew - the <asp:Literal/> tags aren't there. Job's a good-un.

OK - so stick it up on the Mono site. Should just work..... just copy over the aspx file and the cs file... Open up a browser.... Surf on over.... BOFFF!! (BOFFF is the sound that bugs make. Don't ask me why!)

Let's have a look then...

Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Cannot find type Minimal

Hmmm... maybe Mono is broken. Let's try it on a proper ASP.NET server. BOFFF!

Yup! Broken there too. What's going wrong?

It turns out that CodeBehind doesn't mean a thing to an ASP.NET server, not any kind of ASP.NET server, not Mono, and not Microsoft. CodeBehind is just a Visual Studio thing. When you hit F5 in Visual Studio, it compiles it up into a dll and drops it in your bin directory. (Hey - don't look at me like that! Whaddaya mean I should know that? I don't NEED to know that, man - I'm an emcad fer chrissakes!!! )

Ohhh-Kaaayyy - let's pop over to the Windows server image and fix that.... tum te tum...

.Net framework SDK command prompt...
cd C:\minimal
mkdir bin
csc /t:library /out:bin\minimal.dll minimal.aspx.cs

Cool - that builds OK - job's a goodun.

Hang on though - quick test.

BOFFF! Bah - getting sick of this - what now?

Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Parser Error Message: Could not load type 'minimal'.

OK - then fire up fuslogvw and check what's going wrong with the load. Ah - there's an error logged in one of the output files.

0x80131107 - WTF is that!! Quick google - aha "BadImageFormatException". Well to cut a long story short, I had compiled the dll using .NET 2.0 and the web site was configured for 1.1 ho hum.

OK - back to mono - well apart from having to add a reference to System.Web (which presumably is included by default on the Microsoft sytem)

So that worked - OK - but was it the minimal-est possible way of doing it. No - I found a couple of other ways of doing it too. It was a fun day.

If you want the functionality that I had imagined CodeBehind should take care of, use the Src attribute in your @Page directive. That way - ASP.NET will compile your bare-behind class on the fly. If you don't have any code-behind functionality, you can just code Inherits="System.Web.UI.Page", and stuff like <asp:Literal/> will just work. Actually - you can even do without the Inherits; an ASP.NET page gets compiled as a System.Web.UI.Page anyway.

But why? You may ask  - well how can I explain this. Did you ever see American Chopper on Discovery channel? It's pretty entertaining to watch a bunch of guys building a motorbike starting with a sketch on the back of a fag packet. Part of the reason it's entertaining is that they are thoroughly competent. They don't get stuck. When the gizmaflotch won't fit behind the whoffle sprocket, one of them will fire up a cutting torch or a grinding machine and remove the offending lump of metal. They can do that, because they aren't scared of it. They know that if they ruin it, they can weld another bit back on, or re-build that whole part of the bike if necessary.

So that's it I suppose - I'm practicing my welding.

Microsoft Press - hall of shame

Posted by Dominic Cronin at Mar 14, 2007 10:45 PM |

Tomorrow I'm doing the last exam for Microsoft Certified Application Developer (MCAD). I've been using the official training pack from Microsoft Press, and frankly, it's appalling. Examining people's programming ability via the medium of multiple choice is dubious enough to start with, but if you're going to do it, at least make sure the answers are correct even under the most pedantic interpretation possible. To be fair, my experience of the actual exams has been that this is the case, but this little example from the sample exam in the training kit should give you the flavour of what I've found myself up against.

You create a Web custom control named Toggle that users can turn on and off. 
The Toggle Control includes a Button control named toggleButton. You write an event handler named toggleButton_Click for the toggleButton.Click event. This event adjusts the BorderStyle property to signify whether the Button is toggled on or off. You want to add code to the Toggle class so that when the toggleButton is clicked, pages that contain instances of Toggle can process custom event handling code. You add the following code to the Toggle class:
public delegate void ChangedValue(object sender, EventArgs e);
public event ChangedValue Changed; protected virtual void OnChanged(EventArgs e) {     if (Changed != null)         Changed(this, e); }
You need to add code to toggleButton_Click so that pages conaining instances of Toggle can handle the ChangedValue event and process custom event handling code. Which of the following enable you to do so? (Choose the correct answer.)
*    OnChangedValue(EventArgs.Empty)
*    Changed(sender, e); *    OnChanged(this, e);
*    ChangedValue(this, e);

The answer given as correct is the first one, but as far as I can see, it should be something like:


I don't write events and wire them up with delegates every day. It took me a little while to figure out that all the anwsers were wrong. (Personally I find some of the conventions here a little alien. I'm used to a world in which event handlers have names like OnThingHappened. With the .NET framework, OnThingHappened is part of the event raising mechanism: Something happens, so your class calls its OnThingHappened member, which raises the event, which some other code will have subscribed to.)

It's not just an isolated example either. One of the programming labs for ASP.NET begins with a "Switchboard" page, with links to the other pages. In the switchboard page, various DataSets are populated and stored in the Cache. In the other pages, these values are unceremoniously whipped out and used, regardless of the fact that there's no guarantee they'll be there. Bear in mind that half the reason anyone would be studying this stuff is that they probably aren't yet an expert. By the time I'd dug into the subject a little, it turned out that you can only use the web application cache for what it says on the box - caching. It's a performance tweak, and you shouldn't be using it to get data from one page to another. There are probably thousands of applications in production right now based on this fundamentally flawed technique.


Microsoft Press... hall of shame!

Strange dreams of nightmare code

Posted by Dominic Cronin at Mar 04, 2007 05:00 PM |
Filed under: ,

One morning this week I woke up to a very strange combination of life and programming. Kind of a "things that make ya go hmm..." moment. Here's how it went:

Some considerable time ago, I began work on a re-write of a Tridion events system. The existing system was so gunged up with layer upon layer of cruft that we decided it was unmaintainable and that we wouldn't touch it unless absolutely necessary. The fickle winds of project management have now blown us back onto the jagged rocks; we ended up dispatching from the new system back to the old code, which turns out to be fairly broken, and I have to mend it. Ouch!

No big deal, you may think, until you realise that the broken piece is a thirty page long stretch of Visual Basic 6. That's thirty pages all in one function. This code handles a Tridion OnComponentSavePost event, and in the process, saves the component four separate times. Each of these saves causes a recursion into the handler, each time from a different place and with a different data state. Depending on the state, various if-then-else blocks either fire or don't, leading to the code being executed in an order very different from what you see laid out as you hit page-down thirty-odd times. As you can imagine, before making even minor changes to this stuff, you have to marinate in the code for quite some time, tracing the various paths of illogic through the smoke-trails of your predecessor's brain-damaged nightmare. One thing's for sure - you know if you touch anything, there's a huge risk that you'll break something else.

If you've ever done this kind of work, you'll know that once you've lived in the code for a few days, there's every likelihood that you'll spend your nights dreaming of it too.

During this time, our seven-month old son, Finlay has had a virus, resulting in some fairly disrupted sleep for us all. Perhaps once every hour or two through the night, the poor lad would cry out, and you'd find yourself awake in response. After a night of this, it becomes increasingly hard to come up out of deep sleep, and one morning at five or six o'clock, and  I found myself in the middle of a dream of scrolling code, hearing a cry, but hearing it as a bug. Huh? How does that work? You hear of people with psychological disorders hearing colours and so forth, and I suppose in the dream world there are no rules. I heard a cry, and experienced it as a sort of "Oh shit, there's another bug." moment.

Finlay's back to health now, and (mostly) sleeping through the night. Maybe some time soon, I will too.

Music licensing petition

Posted by Dominic Cronin at Feb 24, 2007 12:35 PM |

On the 10th December last year, I took advantage of the new e-petitions feature of the Prime Minister's web site, to create a petition highlighting the problems caused by the current regime in the UK for licensing music and dance (or indeed entertainment in general).

I'm a libertarian at heart, and I believe that unless there's a good reason against it, people should be pretty much allowed to get on with their lives. Unfortunately, the Sir Humphreys managed to slip an act through parliament which made it illegal to perform music and the like in many situations which previously had been unencumbered by such nonsense. Well that plainly won't do, and neither will the fact that they ignored the previous petition.

I'm delighted to say that in such a short space of time, the petition has gathered sufficient signatures to put it in the top five. It has attracted press attention from Libby Purves of The Times, and more recently has been the subject of an article in The Stage.

I really hope it's going to do some good. The cynic in my says the jury's still out, but in the meantime, let's keep our fingers crossed.

More information can be found over at http://http//

Dutch web site accessibility law

Posted by Dominic Cronin at Jan 12, 2007 09:30 PM |

Quirksmode noted that, since September, Dutch government websites have had to be accessible. Oh and then Ajaxian linked quirksmode with "Be Accessible, or Break the Law", and all of a sudden it's a hot topic.

I've worked on Dutch government web sites myself, back when this was an internal initiative called "Drempels weg" (Removing obstacles). After retro-fitting a text-only version of one important site, we were very glad that the next one we worked on had accessibility designed in from the beginning.

Here then is a shout-out to all the people I worked with on those sites, and to my numerous colleagues that are currently busy with other government sites.

Sometimes, it's nice to be able to see a bit of progress. I'm sure this is all very much appreciated by the people who need web sites to be accessible.


Posted by Dominic Cronin at Jan 11, 2007 09:45 PM |

(Via Jeremy Miller)


WATIR was the first thing that ever made me interested enough to install Ruby. The idea is great; browser-based testing of your web site. You write scripts that drive the browser. When the main output of your software development process is a web site, any tools that allow you to run automated tests are at a premium.

The only thing that made me break stride was Ruby. Sure enough - I like playing with new languages, but it was a disappointment to learn that I'd have to learn yet another to get the benefit. Anyway - your customer doesn't want to hear that you're planning to add yet another hot skill to the training requirements for the team.

But now, there's Watin. All the same good stuff as Watir, but you can write your scripts in C#. I'm itching to have a go.