XSL Variable Quirks

I'm still working on our Google Checkout integration at work. I have the web service done, but now I need to process the notifications from Google and update our database accordingly. This morning I was working on translating the XML from Google's 'New Order Notification' into a simpler XML that I can use to insert the order into our database by translating it through an XSL stylesheet. While doing so, I ran into a little quirk in how XSL translations are done.

I was splitting the name into pieces for first name, middle initial, and last name. While going through the various ways the name could be split, I was setting variables with the values. After all of the processing, I was using the variables to set the XML pieces that I needed. But I was getting errors saying that a couple of my variables weren't registered.

So I did some searching to find out what was up since I don't have a lot of experience with XSL (hence the issue I ran into). Apparently variables have VERY LIMITED scope. I was setting the variables with conditional statements inside of a template that was passed the name node to split.

CODE:
  1. <xsl:variable name="ContactFirstName" select="substring-before($name, ' ')" />
  2. <xsl:variable name="rest" select="substring-after($name, ' ')" />
  3. <xsl:choose>
  4.     <xsl:when test='contains($rest, ' ')'>
  5.         <xsl:variable name="ContactMiddleInitial" select="substring-before($rest, ' ')" />
  6.         <xsl:variable name="ContactLastName" select="substring-after($rest, ' ')" />
  7.     </xsl:when>
  8.     <xsl:otherwise>
  9.         <xsl:variable name="ContactMiddleInitial" select="''" />
  10.         <xsl:variable name="ContactLastName" select="$rest" />
  11.     </xsl:otherwise>
  12. </xsl:choose>
  13. <FirstName><xsl:value-of select="$ContactFirstName" /></FirstName>
  14. <MiddleInitial><xsl:value-of select="$ContactMiddleInitial" /></MiddleInitial>
  15. <LastName><xsl:value-of select="$ContactLastName" /></LastName>

Doing the above code, I got errors that the ContactMiddleInitial and ContactLastName variables weren't registered. I was confused because they were set no matter what from the conditions. But apparently the xsl:variable in each case had a parent of either xsl:when or xsl:otherwise, and they weren't available outside of that. I didn't realize that.

So I changed my code to the following and all was fine:

CODE:
  1. <xsl:variable name="ContactFirstName" select="substring-before($name, ' ')" />
  2. <xsl:variable name="rest" select="substring-after($name, ' ')" />
  3. <xsl:choose>
  4.     <xsl:when test='contains($rest, ' ')'>
  5.         <xsl:variable name="ContactMiddleInitial" select="substring-before($rest, ' ')" />
  6.         <xsl:variable name="ContactLastName" select="substring-after($rest, ' ')" />
  7.         <FirstName><xsl:value-of select="$ContactFirstName" /></FirstName>
  8.         <MiddleInitial><xsl:value-of select="$ContactMiddleInitial" /></MiddleInitial>
  9.         <LastName><xsl:value-of select="$ContactLastName" /></LastName>
  10.     </xsl:when>
  11.     <xsl:otherwise>
  12.         <xsl:variable name="ContactMiddleInitial" select="''" />
  13.         <xsl:variable name="ContactLastName" select="$rest" />
  14.         <FirstName><xsl:value-of select="$ContactFirstName" /></FirstName>
  15.         <MiddleInitial><xsl:value-of select="$ContactMiddleInitial" /></MiddleInitial>
  16.         <LastName><xsl:value-of select="$ContactLastName" /></LastName>
  17.     </xsl:otherwise>
  18. </xsl:choose>

Seems kinda silly to me that you can't do what I tried in the first case. But I guess that's how the language is set up. The first question on this page has more detailed info on this: Q. Can I change the value of an XSLT variable?

This is mostly for my benefit in case I run into this issue again. But maybe it will help someone else out there. See ... I can write tech-related posts.

Comments have been disabled for this entry.