Applying templates

C

Christoph

I'm still learning how to write stylesheets and the ones I've come up with
for learning purposes are pretty simple and straightforward. I can get it
to work, but probably not in the most ideal way.

I have a node in the XML I'm transforming that contains CRLFs. I did a
search on how to do a search/replace but am not 100% sure how to fit it into
my template. Here is a sample xml record:

<UserRecordRoot>
<UserItems>
<UserItem>
<uid>MyUserId</uid>
<lastLogin>2002-02-21 01:04:36</lastLogin>
<country>USA</country>
<comments>
Comments Line 1
Comments Line 2
Comments Line 3
</comments>
</UserItem>
</UserItems>
</UserRecordRoot>

Here is my XSL

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:eek:utput method="html"/>

<xsl:template match="UserItems">
<html>
<head>
<title>Game Sets</title>
</head>
<body>
<h1>Users</h1>
<table border="1" width="100%">
<tr>
<th>User</th>
<th>Last Login</th>
<th>Country</th>
<th>Comments</th>
</tr>
<xsl:for-each select="UserItem">
<tr>
<td valign="top">
<xsl:copy-of select="name"/>
</td>
<td valign="top">
<xsl:copy-of select="lastLogin"/>
</td>
<td valign="top">
<xsl:copy-of select="country"/>
</td>
<td valign="top" width="25%">
<xsl:value-of select="comments"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

<xsl:template match="comments">
<xsl:call-template name="replace">
<xsl:with-param name="string" select="."/>
</xsl:call-template>
</xsl:template>

// I found the below on one of the sites listed in my google search
<xsl:template name="replace">
<xsl:param name="string"/>
<xsl:choose>
<xsl:when test="contains($string,'
')">
<xsl:value-of select="substring-before($string,'
')"/>
<br/>
<xsl:call-template name="replace">
<xsl:with-param name="string"
select="substring-after($string,'
')"/>
</xsl:call-template>
</xsl:when>
<xsl:eek:therwise>
<xsl:value-of select="$string"/>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

The UserItems template is simpe, straightfoward and works. I'm just not
sure how to make it so that the comments node matches the template of the
same name and thus triggering the replace template. How can I get this
done?

thnx,
Christoph
 
J

Joe Kesselman

Christoph said:
The UserItems template is simpe, straightfoward and works. I'm just not
sure how to make it so that the comments node matches the template of the
same name and thus triggering the replace template. How can I get this
done?

Replace
<xsl:value-of select="comments"/>
with
<xsl:apply-templates select="comments"/>

I would suggest doing the same thing with the UserItem, actually --
replace the for-each with
<xsl:apply-templates select="UserItem"/>

and move the logic into a template:

<xsl:template match="UserItem">
<xsl:for-each select="UserItem">
<tr>
<td valign="top">
<xsl:copy-of select="name"/>
</td>
<td valign="top">
<xsl:copy-of select="lastLogin"/>
</td>
<td valign="top">
<xsl:copy-of select="country"/>
</td>
<td valign="top" width="25%">
<xsl:apply-templates select="comments"/>
</td>
</tr>
</xsl:for-each>
</xsl:template

Generally this approach -- separately say "process these" and "here's
how to process them" and let XSLT tie the two together -- is more
flexible. It doesn't make much difference in this case since you're
explicitly saying what nodes to continue processing with, but it will
matter when you want to say things like "process all the children".

You can write procedural XSLT... but it's better to think of it as
declarative.
 
J

Joe Kesselman

(Whups. Typo in first version of this note; corrected here.)
The UserItems template is simpe, straightfoward and works. I'm just not
sure how to make it so that the comments node matches the template of the
same name and thus triggering the replace template. How can I get this
done?

Replace
<xsl:value-of select="comments"/>
with
<xsl:apply-templates select="comments"/>

I would suggest doing the same thing with the UserItem, actually --
replace the for-each with
<xsl:apply-templates select="UserItem"/>

and move the logic into a template:

<xsl:template match="UserItem">
<tr>
<td valign="top">
<xsl:copy-of select="name"/>
</td>
<td valign="top">
<xsl:copy-of select="lastLogin"/>
</td>
<td valign="top">
<xsl:copy-of select="country"/>
</td>
<td valign="top" width="25%">
<xsl:apply-templates select="comments"/>
</td>
</tr>
</xsl:template

Generally this approach -- separately say "process these" and "here's
how to process them" and let XSLT tie the two together -- is more
flexible. It doesn't make much difference in this case since you're
explicitly saying what nodes to continue processing with, but it will
matter when you want to say things like "process all the children".

You can write procedural XSLT... but it's better to think of it as
declarative.
 
J

Joe Kesselman

(Whups. Typo in first version of this note; corrected here.)
The UserItems template is simpe, straightfoward and works. I'm just not
sure how to make it so that the comments node matches the template of the
same name and thus triggering the replace template. How can I get this
done?

Replace
<xsl:value-of select="comments"/>
with
<xsl:apply-templates select="comments"/>

I would suggest doing the same thing with the UserItem, actually --
replace the for-each with
<xsl:apply-templates select="UserItem"/>

and move the logic into a template:

<xsl:template match="UserItem">
<tr>
<td valign="top">
<xsl:copy-of select="name"/>
</td>
<td valign="top">
<xsl:copy-of select="lastLogin"/>
</td>
<td valign="top">
<xsl:copy-of select="country"/>
</td>
<td valign="top" width="25%">
<xsl:apply-templates select="comments"/>
</td>
</tr>
</xsl:template>

Generally this approach -- separately say "process these" and "here's
how to process them" and let XSLT tie the two together -- is more
flexible. It doesn't make much difference in this case since you're
explicitly saying what nodes to continue processing with, but it will
matter when you want to say things like "process all the children".

You can write procedural XSLT... but it's better to think of it as
declarative.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top