0
votes

I am in the process of creating my first xslt stylesheet and am finding it difficult and I already owe thanks to a number of people in this forum for help provided. I do have another question though that I hope someone may be able to help with.

Here is a sample of the xml I am working with....

<tr layoutcode="" type="categoryhead">
    <td colname="1">CatHead[~CAP]Short-term securities[#~CAP] 12.19%</td> (a)
    <td colname="2"/>
    <td colname="3"/>
    <td colname="4"/>
 </tr>
 <tr layoutcode="" type="aggregated">
    <td colname="1"/>
    <td colname="2"><strong>Abbott Laboratories</strong><strong><sup>[Category Caption]</sup></strong><sup>0.00</sup> due 4/4/2014 - 5/28/20143</td> (b)
    <td colname="3">88,300</td>
    <td colname="4">88,290</td>
 </tr>

What I want to do is to to replace the text "[Category Caption]" on line (b) with the text "Short-term securities" from line (a). Using the following xslt I can do that but I lose the formatting tags <strong> and <sup>. Here the variable $TargetReplacementToken has the value "[Category Caption]".....

<xsl:template match="tr/td">
        <xsl:choose>
            <xsl:when test="contains(., $TargetReplacementToken)">
                <!-- the td element contains the 'TargetReplacementToken' token/-->
                <xsl:variable name="result" select="substring-after(substring-before((preceding::tr[@type = 'categoryhead']/td[contains(., 'CatHead')])[last()], '[#~CAP]), '[~CAP])"/>
                <xsl:copy>
                    <xsl:apply-templates select="@*" />
                    <xsl:copy-of select="substring-before(., $TargetReplacementToken)" />
                    <xsl:copy-of select="$result" />
                    <xsl:copy-of select="substring-after(., $TargetReplacementToken)" />
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

... such that the transformed xml line looks like this...

<td colname="2">Abbott Laboratories Short-term securities 0.00 due 4/4/2014 - 5/28/20143</td>

Is there a way of enhancing the xslt code to perform the find and replace text and maintain the <strong> and <sup>, and indeed any other possible tags?

I would like the node to look like this..

<td colname="2"><strong>Abbott Laboratories</strong><strong><sup> Short-term securities </sup></strong><sup>0.00</sup> due 4/4/2014 - 5/28/20143</td>

Many thanks in advance.

fordprefect141

1
Is it the only sup element? Would it be ok to replace all text nodes inside sups? - CodeManX
In this case I only want to replace what is inside the <sup> tag based on the original text being "[Category Caption]". That much I have working but it loses all tags within the "td" element. I don't know if converting the td node to text would help or even if it is possible. - FordPrefect141

1 Answers

0
votes

You can use an additional template to match all sup whose text() is equal to [Category Caption]:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="sup[text()='[Category Caption]']">
    <xsl:variable name="result" select="substring-after(substring-before((preceding::tr[@type = 'categoryhead']/td[contains(., 'CatHead')])[last()], '[#~CAP]'), '[~CAP]')"/>
    <xsl:element name="{name()}">
      <xsl:value-of select="$result"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Output:

<?xml version="1.0" encoding="utf-8"?>
<table>
  <tr layoutcode="" type="categoryhead">
    <td colname="1">CatHead[~CAP]Short-term securities[#~CAP] 12.19%</td> (a)
    <td colname="2" />
    <td colname="3" />
    <td colname="4" />
  </tr>
  <tr layoutcode="" type="aggregated">
    <td colname="1" />
    <td colname="2">
      <strong>Abbott Laboratories</strong><strong>
        <sup>Short-term securities</sup>
      </strong><sup>0.00</sup> due 4/4/2014 - 5/28/20143
    </td> (b)
    <td colname="3">88,300</td>
    <td colname="4">88,290</td>
  </tr>
</table>