February 8, 2007

Microsoft-free Daily Grind

If you like the "Daily Grind" by Mike Gunderloy you might like its Microsoft-free version "Quick Links" at the "A fresh Cup" site ("Notes from a recovering Microsoft addict") too. Worth subscribing anyway. ...

AdSense Watch Toolbar v1.0

If you were using my little AdSense Watch Toolbar 1.0b version and it expired, I'm sorry about that, go and download new version 1.0, which has no time limitation. After 6 months in beta I can say AdSense Watch proved to be pretty stable, which is kinda unusual for screenscraping applications ...

February 6, 2007

Generating XML entity references (&foo;) with XSLT: XSLT 2.0 to the rescue

Here is a problem: XSLT 1.0 sucks on generating XML character or entity references. I mean getting &foo; out of XSLT 1.0 is hard. The only ugly solution is disable-output-escaping hack, but it's a) optional, b)doesn't work in all scenarios (only when XSLT engine controls output serialization into bytes and c) works only on ...

In XSLT 2.0 disable-output-escaping is deprecated. New facility for the problem is called Character Maps. Character maps are simpler, better and don't mess with data model. Formal definition:

A character map allows a specific character appearing in a text or attribute node in the final result tree to be substituted by a specified string of characters during serialization. The effect of character maps is defined in [XSLT and XQuery Serialization].

This is basically declarative replace for XSLT output.

Let's say you want to generate this XUL fragment (real world question):

<menuitem label="&context.add.building;"/>

XSLT 2.0 solution would be to define a character map, which maps ampersand character to ugh... ampersand character :) For this to make sense you should realize that mapping a character effectively disables its XML or HTML escaping. It's like you say "I want this character to be outputted as this string and don't mess with it you, the engine". That's powerful enough even to disable escaping of reserved characters such as & and <.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output use-character-maps="xul" />
    <xsl:character-map name="xul">
        <xsl:output-character character="&amp;" string='&amp;'/>
    </xsl:character-map>
    <xsl:template match="contextMenu">
	<menuitem label="&amp;context.add.{name()}"/>
    </xsl:template>
</xsl:stylesheet>

Awesome. I can't wait, I want this in XSLT 1.0 too. I think I'm going to implement character maps for nxslt.exe tool. The only problem is how to provide mapping info. I'll post about it next time.

[Tested with Saxon 8.8B for .NET].

Googlomania

Google somehow seems to be inaccessible (down?) from my place for at least 15 minutes now and I already feel uncomfortable  if not desperate. I want my mail, news and search back! Seriously, WTF? How come can I be so dependent on google? Ok, great, who else does search on the ...

Why XML

Everybody who speaks English can communicate with anybody else who also happens to speak English. You can talk, you can mail, you can read books written in English by others. Sure you can invent your own language, no big deal. You can even make somebody learn it and then ...

February 5, 2007

Expandable archive list for MovableType

I'm blogging since March 2003 and as time goes I noticed my blog archive list became way too long and ugly. Finally I figured out how to generate it in a nice expandable list form you can see on the right. Here is a my small how to for MovableType powered ...

1. Install Archive Date Header Plugin from Adam Kalsey. This allows to generate year headers.

2. Insert this piece of Javascript somewhere - if you have common js file that would be the best, but at worse just paste it before </head> in your template. It's a function to handle expand/collapse year clicks.

<script type="text/javascript">
  function ec(e) {
    var targ;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ) {
      rows = targ.parentNode.getElementsByTagName("DIV");
      collapsed= targ.className == "year-hdr collapsed";
      targ.className = collapsed?  "year-hdr expanded" : "year-hdr collapsed";
      for(i=0; i < rows.length; i++)
        rows[i].style.display = collapsed? "block" : "none";
    }
  }
</script>

3. Use the following snippet in your template to generate expandable archive list. It generates nested list of archives with year headers.

<div class="side">
  <div>
    <MTArchiveList archive_type="Monthly">
      <MTArchiveDateHeader>
        </div><div>
        <p class="year-hdr collapsed"
          onclick="ec(event)"
          id="archive<MTArchiveDate format="%Y">">
             <MTArchiveDate format="%Y">
        <p>
      </MTArchiveDateHeader>
      <div class="month-row">
        <img src="images/folder.gif" align="middle"/> <a
          href="<$MTArchiveLink$>"><MTArchiveDate format="%B"></a>
       </div>
    </MTArchiveList>
  </div>
</div>

4. If you prefer the current year to be expanded by default, insert this piece of javascript after above template:

<script type="text/javascript">
  year = document.getElementById("archive" + (new Date()).getFullYear());
  if (year) {
    year.className = "year-hdr expanded";
    rows = year.parentNode.getElementsByTagName("DIV");
    for(i=0; i < rows.length; i++)
        rows[i].style.display = "block";
  }
</script>

5. Define CSS styles. Here are my definitions:

.year-hdr {
  cursor: pointer;
  cursor:hand;
  font-size: 120%;
  font-weight: bold;
  background-repeat: no-repeat;
  background-position: top left;
  padding:2px;
}

.collapsed {
  background-image: url(images/plus.gif);
 }

.expanded {
  background-image: url(images/solid.gif);
}

.month-row {
  display: none; 
  padding-left: 2em;
}

Done.

February 4, 2007

On embedding XSLT stylesheets into assemblies

I was writing about loading XSLT stylesheets embedded into assemblies (dll or exe) recently and Richard Quinn asked this very legitimate question: But why oh why would anyone embed their XSLT in the assembly? The point is to separate design from logic. Even if the xslt does a non-presentational transform ...

Well, having XSLT stylesheets externally no doubt has many benefits. But embedding XSLT stylesheets into deploy units (be it dll, exe or jar) is also done not without a reason. After all two the most often used in the wild XSLT stylesheets are embedded. I'm talking about res://msxml.dll/defaultss.xsl (technically not XSLT stylesheet) and chrome://global/content/xml/XMLPrettyPrint.xsl  - respectively Internet Explorer and Firefox XML pretty printers.

Embedding stylesheet doesn't necessarily mean coupling presentation and logic layers, in fact it has nothing to do with any application design issues. It's just deployment strategy and in that sense XSLT stylesheets aren't different from images or scripts.

Sure, when your XSLT file is just laying around you can tweak it without reinstalling application (sometimes even without restarting it). Sometimes that's useful and sometimes you don't want users to play with your stylesheet, because allowing that means:

  1. more code to write - you have to anticipate possible stylesheet changes, corruption or removal
  2. more testing
  3. potential security hole, because don't forget XSLT is a programming language and if that's not enough it can include extensions so that enables lots of interesting code injection scenarios for black hats. Sure with .NET 2.0 XSLT security options you can limit what XSLT stylesheet can perform, but then - it's your stylesheet and you are limiting yourself in the first place.

Again, sometimes deployment is easier if you don't have to bother about all that little files to be placed into the right place.

Some people embed, obfuscate and encrypt XSLT stylesheets trying to prevent reverse engineering. Well, apparently they do it for a reason too.

Performance is another interesting point. I think loading string resources should be a little bit faster than loading from the disk. Didn't test it though.

But the whole new era of XSLT embedding is going to start when XSLT finally becomes widely compilable into executable code. Next Visual Studio (codename Orcas, expected later this year) will include XSLTC.EXE - XSLT to MSIL compiler. That would add another benefit - save on XSLT compilation, which is time and resource hog.

If you do embed your XSLT stylesheets, I wonder what are your reasons?