Re: [xsl] creating tags around a string

Subject: Re: [xsl] creating tags around a string
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Mon, 17 Apr 2006 18:02:44 -0400
Troy,

Ordinarily, we don't create "tags" in XSLT. Instead, we use the language's built-in capability to build a structure of nodes that represents ("is") an XML document, and then rely on a downstream component after the transformation (a "serializer") to write tags-and-text -- XML syntax -- that represents ("is") the desired result.

This can be confusing since the way we represent these structures (which we call "trees") in a stylesheet is the same as we do in a document -- using tags and text.

This means that instead of what you have (reformatted for clarity):

<xsl:text>&lt;fname&gt;</xsl:text>
   <xsl:value-of select="."/>
<xsl:text>&lt;/fname&gt;</xsl:text>

one could simply write


<fname>
  <xsl:value-of select="."/>
</fname>

which would instruct the processor to attach a branch to the tree like this:

+ [element 'fname'
   + [value of '.'] ]

which is to say an element named 'fname', containing a bit of text (the value of "."). No tags have to be written until the tree to which this branch is attached is built by the transformation, at which point we could simply hand it to the serializer, which for this bit would write "<fname>Bob</fname>" (if our value had been "Bob").

Is there any reason you can't do this?

In contrast, what you have would do this:

+ [text '<fname>']
+ [value of '.']
+ [text '</fname>']

which is both more work -- think about adding attributes, keeping the nesting right, etc. -- and hard to write, debug and maintain.

If you could build trees instead of write tags-and-text, it would make the rest of what you need to do (handling variant input) much easier, along with everything else.

For everyday purposes, using XSLT to write explicit tags is considered a no-no, since there's almost never a good reason to do it. And no wonder: the other way is how the language is designed to work.

Cheers,
Wendell

At 05:17 PM 4/17/2006, you wrote:
Hello,

I am trying to create some tags around a string of names and was wondering
what is the best way to do this. I have come up with the below xslt, but
it will only work limited instances. Any other ideas would be grand. For
example, if I have any middle names or more than a first/last name, the
xslt breaks.

Thanks!
-troy

=====================================================

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:foo="http://whatever";>
        <xsl:output method="text"/>
        <xsl:function name="foo:mesplit">
                <xsl:param name="inString"/>
                <xsl:param name="delimiter"/>
                <xsl:variable name="tokenizedSample" select="
tokenize($inString,$delimiter)"/>
                <xsl:for-each select="$tokenizedSample">
                        <xsl:variable name="thisstick">
                                <xsl:value-of select="."/>
                        </xsl:variable>
                        <xsl:choose>
                                <xsl:when test="contains(.,',')">
                                        <xsl:value-of select="
foo:mesplit($thisstick,',')"/>
                                </xsl:when>
                                <xsl:when test="contains(., ' ')">
                                        <xsl:value-of select="foo:mesplit(
normalize-space($thisstick),' ')"/>
                                </xsl:when>
                                <xsl:otherwise>
                                        <xsl:if test=".">
                                                <xsl:if test="
index-of($tokenizedSample, .) = 1">
                                                        <xsl:text>  </
xsl:text>
                                                        <xsl:text>
&lt;fname&gt;</xsl:text>
                                                                <
xsl:value-of select="."/>
                                                        <xsl:text>
&lt;/fname&gt;</xsl:text>
                                                </xsl:if>
                                                <xsl:if test="
index-of($tokenizedSample, .) = 2">
                                                        <xsl:text>
&lt;lname&gt;</xsl:text>
                                                                <
xsl:value-of select="."/>
                                                        <xsl:text>
&lt;/lname&gt;</xsl:text>
                                                </xsl:if>
                                        </xsl:if>
                                </xsl:otherwise>
                        </xsl:choose>
                </xsl:for-each>
        </xsl:function>

<xsl:template match="/">
                <xsl:value-of select="foo:mesplit('Al Stick, Tom She, Dick
Burg and Harry Ward', 'and')"/>
        </xsl:template>
</xsl:stylesheet>

======================

desired output:

<fname>Al</fname><lname>Stick</lname>
<fname>Tom</fname><lname>She</lname>
<fname>Dick</fname><lname>Burg</lname>
<fname>Harry</fname><lname>Ward</lname>


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

Current Thread