title: In XSLT, Replace one class value when there are multiple values
body: <p>I'm working with an XSL transformation that's being applied to an HTML document. Relevant HTML example:</p>
  
  <pre><code>&lt;div class="row home-row"&gt;
      &lt;p&gt;Hello&lt;/p&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>I select items that match this with the following XSL (which is working nicely):</p>
  
  <pre><code>&lt;xsl:template match="//*[contains(concat(' ', normalize-space(@class), ' '), ' row ')]" priority="1"&gt;
  </code></pre>
  
  <p>Then, if a condition I've earlier checked matches, I replace "row" with "row-fluid" like this:</p>
  
  <pre><code>&lt;xsl:variable name="original-row-class" select="string(@class)" /&gt;
  &lt;xsl:variable name="row-class"&gt;
                    &lt;xsl:call-template name="replace"&gt;
                          &lt;xsl:with-param name="text" select="$original-row-class" /&gt;    
                          &lt;xsl:with-param name="replace" select="' row '" /&gt;
                          &lt;xsl:with-param name="by" select="' row-fluid '" /&gt;
                      &lt;/xsl:call-template&gt;
                  &lt;/xsl:variable&gt;
                  &lt;xsl:copy&gt;
                      &lt;xsl:attribute name="class"&gt;&lt;xsl:value-of select="$row-class" /&gt;&lt;/xsl:attribute&gt;
                      &lt;xsl:apply-templates select="@*[local-name() != 'class']|node()[local-name() != 'class']"/&gt;
                  &lt;/xsl:copy&gt;
  </code></pre>
  
  <p>This also works fairly well, except that it replaces all mentions of "row" with "row-fluid" even if they are inside "home-row". What I'd like to do is change the "row" classes to "row-fluid", but ignore the "home-row" classes while doing so. Is this possible?</p>
  
  <p>I should mention that I am locked into XSLT 1.0.</p>
  
  <p><strong>Update</strong>: adding the replace template below (should've thought of that earlier!):</p>
  
  <pre><code>&lt;xsl:template name="replace"&gt;
      &lt;xsl:param name="text" /&gt;
      &lt;xsl:param name="replace" /&gt;
      &lt;xsl:param name="by" /&gt;
      &lt;xsl:choose&gt;
        &lt;xsl:when test="contains($text, $replace)"&gt;
          &lt;xsl:value-of select="substring-before($text,$replace)" /&gt;
          &lt;xsl:value-of select="$by" /&gt;
          &lt;xsl:call-template name="replace"&gt;
            &lt;xsl:with-param name="text" select="substring-after($text,$replace)" /&gt;
            &lt;xsl:with-param name="replace" select="$replace" /&gt;
            &lt;xsl:with-param name="by" select="$by" /&gt;
          &lt;/xsl:call-template&gt;
        &lt;/xsl:when&gt;
        &lt;xsl:otherwise&gt;
          &lt;xsl:value-of select="$text" /&gt;
        &lt;/xsl:otherwise&gt;
      &lt;/xsl:choose&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>Thanks,
  Jonathan</p>