1

I have the following tokenizing template implemented in my XSLT.

<xsl:template match="sporting_arena/text()[normalize-space()]" name="split">
 <xsl:param name="pText" select="."/>
 <xsl:if test="normalize-space($pText)">
   <li>
     <xsl:call-template name="replace">
       <xsl:with-param name="pText" select="substring-before(concat($pText, ';'), ';')"/>
     </xsl:call-template>
   </li>
   <xsl:call-template name="split">
     <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
   </xsl:call-template>
 </xsl:if>

<xsl:template name="replace">
   <xsl:param name="pText"/>
   <xsl:if test="normalize-space($pText)">
       <xsl:value-of select="substring-before(concat($pText, '*'),'*')"/>
       <xsl:if test="contains($pText, '*')">
           <br/>
         <xsl:call-template name="replace">
           <xsl:with-param name="pText" select="substring-after($pText, '*')"/>
         </xsl:call-template>
       </xsl:if>
    </xsl:if>
</xsl:template> 

I'm wondering if it is possible to add to this tokenizing system the ability to bold or italicize certain words in my XML element text using the same delimiter approach with a delimiter on each side of a word to indicate either bold or italicized.

XML Example with current system:

        <sporting_arena>
    Adelaide Oval: An awesome new bike and truck that drove up* a hill and never came back.; 
The delimiter I choose here * places this text on a new line and now I'm;
On a new dot point. 
        </sporting_arena>
lfurini
  • 3,729
  • 4
  • 30
  • 48
user2285167
  • 55
  • 1
  • 2
  • 11

1 Answers1

3

"I'm wondering if it is possible to add to this tokenizing system the ability to bold or italicize certain words in my XML element text using the same delimiter approach with a delimiter on each side of a word to indicate either bold or italicized."

Yes, it is possible. And at this point you should be able to implement this yourself, using the same principle as the one utilized by the tokenizing template (which you call "split"). Creating a token tagged as <li> is no different from creating one tagged <b> or <i>.


Edit:

In response to:

"I think there is a difference: while partitioning the text into li elements, every fragment of text eventually ends up inside a list item, and the delimiter ; marks where a list item should end and another immediately start. Conversely, the bold or italic markup would apply only to a text portion between a starting and an ending delimiter."

The required change is rather trivial. Consider the following example:

<xsl:template name="italic">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="'*'"/>
    <xsl:choose>
        <xsl:when test="contains($text, $delimiter) and contains(substring-after($text, $delimiter), $delimiter)">
            <xsl:value-of select="substring-before($text, $delimiter)"/>
            <i>
                <xsl:value-of select="substring-before(substring-after($text, $delimiter), $delimiter)"/>
            </i>
            <!-- recursive call -->
            <xsl:call-template name="italic">
                <xsl:with-param name="text" select="substring-after(substring-after($text, $delimiter), $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

When this template is called as:

<p>
    <xsl:call-template name="italic">
        <xsl:with-param name="text" select="input"/>
    </xsl:call-template>
</p>

with the input being:

<input>Lorem ipsum *dolor* sit amet, *consectetuer* adipiscing * elit.</input>

the result will be:

<p>Lorem ipsum <i>dolor</i> sit amet, <i>consectetuer</i> adipiscing * elit.</p>

Note that the last, odd delimiter is passed to the output as is.

You could generalize this template to handle other types of markup (e.g. bold) by parametrizing the name of the token element to create.

--
P.S. This solution proudly uses xsl:choose. xsl:choose is an integral part of the XSLT language, and there is absolutely nothing wrong with using it to its full advantage. It adds clarity to the code, while artificial attempts to avoid using it only end up obfuscating the code unnecessarily.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • I think there is a difference: while partitioning the text into `li` elements, every fragment of text eventually ends up inside a list item, and the delimiter `;` marks where a list item should end and another immediately start. Conversely, the bold or italic markup would apply only to a text portion between a starting and an ending delimiter. – lfurini Apr 09 '15 at 11:34
  • I'm have difficulty implementing this. I believe I can only call one template inside my split
  • otherwise it outputs the XML element twice. Do I have to combine the replace and italicize template in some way, so I only have to make one template call in the
  • of my split template not resulting in double output that occurs if I call both replace and italicize in
  • of the split template. – user2285167 Apr 09 '15 at 17:34
  • 1
    You need to call your templates **in succession**. Each token in an upper level template needs to be sent to the next template in order. This is assuming you are not nesting bold inside italic AND italic inside bold - otherwise it gets more complex. – michael.hor257k Apr 09 '15 at 17:37