xsl-list
[Top] [All Lists]

Re: Using XSLT to add markup to a document

2003-07-07 11:37:56
Hi Jeni, David and Wendell,

While this is a nice solution, it will not produce good results in the case
when one of  the search strings is the start of another of the search
strings.

Also, all possible search strings are hard-coded in the code within an
xsl:choose.

This is not going to help in the case when we need to call this template,
passing it a parameter containing an unknown number of search strings.

Even if you try to use the xsl:choose approach with a moderate number of
predefined strings (e.g. 5 - 10), the code will increase quadratically to
the number of search strings.


Or am I missing something?



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL



"Jeni Tennison" <jeni(_at_)jenitennison(_dot_)com> wrote in message
news:4919758491(_dot_)20030707165132(_at_)jenitennison(_dot_)com(_dot_)(_dot_)(_dot_)
Hi David,

I notice that most XSLT 1.0 solutions use recursive templates and
wondered if there is any benefit in a solution that re-applies
templates to text nodes many times, rather than explicitly calling a
recursive template. For moderately big files it seems to perform
quite well, though I haven't tested it too much, so there may be
hidden problems. I guess this approach is essentially the same as
recursion, but you don't have to figure out which matched string
comes first (though you do need node-set).

What you're doing in your stylesheet, as far as I can tell, is
creating new text nodes for the substrings before and after the
matched string. In general, it's a bad idea to create new nodes if you
can get away with using a string or number instead because nodes take
up a lot more memory than simple values. Also, all you've done really
is add a level of indirection -- rather than call the template
recursively directly, you're calling it recursively via a template
that matches the new text node that you've generated -- which might
add a little to the time (it certainly won't make it quicker).

So I'm afraid that I can't see much benefit in the approach you're
suggesting. It should be more efficient to use:

<xsl:template match="text()" priority="2"><!-- need priority to overcome
the
node match below -->
  <xsl:call-template name="markup">
    <xsl:with-param name="text" select="."/>
  </xsl:call-template>
</xsl:template>

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

<xsl:template name="markup">
  <xsl:param name="text"/>
  <xsl:choose>
    <xsl:when test="contains($text, 'document')">
      <xsl:call-template name="markup">
        <xsl:with-param name="text"
          select="substring-before($text, 'document')" />
      </xsl:call-template>
      <special>document</special>
      <xsl:call-template name="markup">
        <xsl:with-param name="text"
          select="substring-after($text, 'document')" />
      </xsl:call-template>
    <xsl:when test="contains($text, 'markup')">
      <xsl:call-template name="markup">
        <xsl:with-param name="text"
          select="substring-before($text, 'markup')" />
      </xsl:call-template>
      <special>markup</special>
      <xsl:call-template name="markup">
        <xsl:with-param name="text"
          select="substring-after($text, 'markup')" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise><xsl:value-of select="$text"/></xsl:otherwise>
  </xsl:choose>
</xsl:template>

But of course you should test it to see if my assumptions are correct.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list






 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list