Page 1 of 1

String processing in XSLT

Posted: Thu Jul 03, 2008 10:23 pm
by SteveB
I am fairly new to XSLT but have been able to figure out most problems that have come up. But this one has me stumped.

The problem: How to take a single block text separated into strings by a delimiting characters (such as semicolons), and break it down into a series of XML elements tagged with identical tags. The strings (and resulting XML elements) will be of various lengths. The number of elements needs to vary.

This came up when I was trying to process a list of faculty members and the degrees they have earned. Some have one degree, others have several. The original data for each faculty member (converted from a text file) looks something like this:

Code: Select all


<para>John Q. Doe, Degree Number One; Degree Number Two; Degree Number Three; Associate Professor</para>
I want to transform it into this:

Code: Select all


<faculty_member>
<first_name>John</first_name>
<initial>Q.</initial>
<last_name>Doe</last_name>
<degree>Degree Number One</degree>
<degree>Degree Number Two</degree>
<degree>Degree Number Three</degree>
<title>Associate Professor</title>
</faculty_member>
I've figured out how to use combinations of substring-before() and substring-after() to extract everything except the list of degrees. You could, of course, do them as one chunk of data. But it would be better to tag them individually.

I suspect that I need a recursive template, but am not sure how to hand off the string from one iteration to the next.

I'm sure the answer to this must be pretty simple. Any suggestions would be appreciated. Thanks.

SB

Re: String processing in XSLT

Posted: Mon Jul 07, 2008 5:32 pm
by Radu
Dear Steve,

Hope this will help,

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="root">
<faculty>
<xsl:for-each select="para">
<faculty_member>
<xsl:variable name="name" select="substring-before(., ',')"/>
<first_name><xsl:value-of select="substring-before($name, ' ')"/></first_name>
<initial><xsl:value-of select="substring-before(substring-after($name, ' '), ' ')"/></initial>
<last_name><xsl:value-of select="substring-after(substring-after($name, ' '), ' ')"/></last_name>
<xsl:call-template name="degrees">
<xsl:with-param name="value" select="substring-after(., ',')"/>
</xsl:call-template>
<a/> </faculty_member>
</xsl:for-each>
</faculty>
</xsl:template>
<xsl:template name="degrees">
<xsl:param name="value" select="''"/>
<xsl:choose>
<xsl:when test="contains($value, ';')">
<degree><xsl:value-of select="substring-before($value, ';')"/></degree>
<xsl:call-template name="degrees">
<xsl:with-param name="value" select="substring-after($value, ';')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<title><xsl:value-of select="$value"/></title>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Regards,
Radu

Re: String processing in XSLT

Posted: Tue Jul 08, 2008 6:25 pm
by SteveB
Radu,

That's perfect!

Your example also cleared up some questions I had about variables and the for-each element.

Much appreciated. Thank you.

Steve