George V. Reilly's Technical Blog

Throwing from XSLT

I needed to add some declarative error checking to some XSLT templates recently. Specifically, I wanted to throw an error if my selects yielded an empty string, indicating that the input XML was wrong.

Unfortunately, there seems to be no easy way of doing this in XSLT, nor in XslTransform. The approved way is to validate against an XSD schema, but for various reasons, I didn't want to go to the hassle of creating one.

I found a partial solution using xsl:message with the terminate="yes" attribute. Under XslTransform.Transform() the following code throws an exception if the XPath expression is empty.

 <xsl:if test="not(/some/xpath/expression)">
     <xsl:message terminate="yes">Missing expression</xsl:message>
 </xsl:if>
 <xsl:value-of select="/some/xpath/expression" />

It doesn't do anything, however, in XMLSpy.

The downside, of course, is that you have to maintain the expression in two places, and the template becomes littered with those annoying tests.

Comments

Chris Bowley said:

This isn't going to help you with XMLSpy but if you are using .NET XSLT then try checking out the
System.Xml.Xsl.XsltArgumentList.AddExtensionObject
mechanism? It worked well for me in a similar scenario.

First create a class containing the additional functions that you need. Then create a System.Xml.Xsl.XsltArgumentList instance and add an instance of your class to it by calling AddExtensionObject together with a namespace URI e.g. "urn:MMF". The XsltArgumentList is passed to
System.Xml.Xsl.XslTransform.Transform().

In the stylesheet add a matching namespace declaration
to the surrounding xsl:stylesheet element e.g.
xmlns:mmfExt="urn:MMF"
Then call any of the class functions wherever a normal XPath function is expected. For example
<xsl:value-of select='mmfExt:PhoneNumberToHexValue($CustSuppMSISDN)'/>

It is a simple matter to substitute the function above with one to throw an exception. It could take XPath function output as a parameter, throw an exception if it is null or return it unchanged if it is non-null.

If you want to avoid duplicate expressions you could assign the value of the expression to an intermediate variable.

Hope this helps.
# March 2, 2006 5:05 AM

Don Demsak said:

Or, an even better solution is to use XML Schema to validate the XML, prior to running the XSLT. XML Validation is what XML Schema was designed to do. This way, if there is a problem, you never even get to the XSLT step.
# March 2, 2006 7:27 AM

Aicha said:

gluks in here....really sucks( delete it

# March 29, 2007 9:06 PM

Aimy said:

Kewl :)

# March 31, 2007 2:05 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)