String processing in XSLT

Here should go questions about transforming XML with XSLT and FOP.
SteveB
Posts: 13
Joined: Sat Feb 02, 2008 6:52 pm

String processing in XSLT

Post 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
Radu
Posts: 9439
Joined: Fri Jul 09, 2004 5:18 pm

Re: String processing in XSLT

Post 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
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
SteveB
Posts: 13
Joined: Sat Feb 02, 2008 6:52 pm

Re: String processing in XSLT

Post 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
Post Reply