Xatapult's XML Blog

26/04/2011

XSLT types against typos

Filed under: How-to,Tips and trics,Uncategorized — xatapult @ 07:13
Tags: ,

Some tiny typing mistakes in your XSLT stylesheet can cause major headaches. Why? Because they go undetected by the standard static and dynamic error checking mechanisms. Something as simple as writing /Filename where it should be /FileName will only show up if your own test/debug efforts find it and will not be trapped by the XSLT engine. Unless… you use the XSLT V2.0 mechanism for type checking.

What’s up?

Assume you have an XML document that looks like this:

<Things>
   <Thing thingid="12345FFD3">...</Thing>
   <Thing thingid="86779EAD0">...</Thing>
   ...
</Things>

In your XSLT stylesheet you have a named template that does something with a thing:

<xsl:template name="ProcessThing">
  <xsl:param name="ThingId"/>
  <xsl:for-each select="/Things/Thing[@id eq $ThingId]">
    <!-- Do something with the thing -->
  </xsl:for-each>
</xsl:template>

Spot the mistake: The author of this template forgot (or didn’t know) that the identifier attribute on a thing was spelled thingid and not id. If you run this, no error message will show up, the for-each loop will simply not execute. Maybe you notice, maybe you don’t (because it was embedded somewhere in a very complicated transformation…). The same for all spelling mistakes in element/attribute names in XPath expressions (like /Things/thing[@thingid eq $ThingId]).

Not nice at all: Your code went into production, the spelling mistake prevented an important part of some calculation from happening. Because of this the client paid too much taxes and now he/she can’t pay you…

Preventive measures

So what can you do? Double check, reread, ferocious debugging, keep fingers crossed, pray… certainly, do it all! But what you really (should) want is the bug to show up in a booming error message. Here is how to do this using the XSLT V2.0 type mechanism (this won’t work in V1.0).

XSLT V2.0 is type aware. You can specify what data type a variable (or parameter) must have for it to be valid. Although this certainly is no panacea for all mistakes, typing errors in XPath expressions can be caught by it.

For instance, if you rewrite the above example as this, the error will show up immediately:

<xsl:template name="ProcessThing">
  <xsl:param name="ThingId"/>
  <xsl:variable name="ThingToProcess" as="element(Thing)"
    select="/Things/Thing[@id eq $ThingId]"/>
  <xsl:for-each select="$ThingToProcess">
    <!-- Do something with the thing -->
  </xsl:for-each>
</xsl:template>

At runtime, the stylesheet processor will notice that /Things/Thing[@id eq $ThingId] does not return the expected <Thing> element but the empty set and will complain about it.

There is even a bonus: If the input document contains an error and has two things with the same id an error will show up also: The $ThingToProcess variable can only contain a single thing, not multiple!

To make this template even better, I would personally also type the parameter:

<xsl:param name="ThingId" as="xs:string" required="yes"/>

This traps forgetting the parameter (because of the required="yes") and also passing empty or multiple values.

Trapping mistakes in the input document

The “types against typos” mechanism can also be used in trapping input document mistakes. (This assumes that you haven’t validated your input document, which is of course the best way to do this, but you know how it is…).

Before using anything, put them in a typed variable first:

<xsl:variable name="Status" as="xs:string" select="@status"/>

No attribute means no value (which differs from the empty string!) and an error will stop the stylesheet.

 

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: