xsl-list
[Top] [All Lists]

Re: [xsl] Placing mark-up in between strings

2006-11-23 02:30:27
Jeff Sese wrote:

  Hi

I have this as a sample:

<p>This is supposed to be my input string with search1, search2, and 
search3.</p>

I want this to be:

<p>This is supposed to be my input string with <replacement 
value="replacement1">search1</replacement>, <replacement 
value="replacement2">search2</replacement>, and <replacement 
value="replacement3">search3</replacement>.</p>

  I wanted to send a response to this problem, but I ran
into a problem while testing it.  It seems that an
atomization takes place somewhere with the paramaters of
ati:replace-specific(), but I can see where.  Any thought?

    drkm[19] ~/xslt/tests
    $ cat replace-with-nodes.xsl
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                    xmlns:xs="http://www.w3.org/2001/XMLSchema";
                    xmlns:ati="ati-ns"
                    version="2.0">

      <!--
          Replace strings with an element constructed from the
          replaced and replacement strings.  Build those elements
          then call ati:replace-with-nodes().
      -->
      <xsl:function name="ati:replace-specific" as="node()+">
        <xsl:param name="input"            as="xs:string"/>
        <xsl:param name="words-to-replace" as="xs:string*"/>
        <xsl:param name="replacement"      as="xs:string*"/>
        <xsl:variable name="new-replacement" as="element()*">
          <xsl:for-each select="1 to count($words-to-replace)">
            <xsl:variable name="i" select="."/>
            <replacement value="{ $replacement[$i] }">
              <xsl:value-of select="$words-to-replace[$i]"/>
            </replacement>
          </xsl:for-each>
        </xsl:variable>
        <xsl:sequence select="
            ati:replace-with-nodes(
                $input,
                $words-to-replace,
                $new-replacement
              )"/>
      </xsl:function>

      <!--
          Replace strings with given nodes.
      -->
      <xsl:function name="ati:replace-with-nodes" as="node()+">
        <xsl:param name="input"            as="xs:string"/>
        <xsl:param name="words-to-replace" as="xs:string*"/>
        <xsl:param name="replacement"      as="node()*"/>
        <xsl:sequence select="
            if ( exists($words-to-replace) ) then
              ati:replace-with-nodes(
                  ati:replace-with-nodes-1(
                      $input, $words-to-replace[1], $replacement[1]
                    ),
                  remove($words-to-replace, 1),
                  remove($replacement, 1)
                )
            else
              $input
          "/>
      </xsl:function>

      <!--
          Internal.  Coroutine for ati:replace-with-nodes().
          Treat a single replacement.
      -->
      <xsl:function name="ati:replace-with-nodes-1" as="node()*">
        <xsl:param name="input"           as="xs:string?"/>
        <xsl:param name="word-to-replace" as="xs:string"/>
        <xsl:param name="replacement"     as="node()"/>
        <xsl:variable name="before" select="
            substring-before($input, $word-to-replace)"/>
        <xsl:choose>
          <xsl:when test="exists($before)">
            <xsl:value-of select="$before"/>
            <xsl:sequence select="$replacement"/>
            <xsl:sequence select="
                ati:replace-with-nodes-1(
                    substring-after($input, $word-to-replace),
                    $word-to-replace,
                    $replacement
                  )"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:sequence select="$input"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:function>

      <!--
          Simple test.
      -->
      <xsl:template name="main">
        <xsl:variable name="input" as="element()">
          <p>This is supposed to be my input string with search1,
            search2, and search3.</p>
        </xsl:variable>
        <xsl:variable name="words" select="
            'search1', 'search2', 'search3'"/>
        <xsl:variable name="replacement" select="
            'replacement1', 'replacement2', 'replacement3'"/>
        <initial>
          <xsl:sequence select="$input/node()"/>
        </initial>
        <replaced>
          <xsl:sequence select="
              ati:replace-specific(
                  string($input),
                  $words,
                  $replacement
                )"/>
        </replaced>
      </xsl:template>

    </xsl:stylesheet>

    drkm[20] ~/xslt/tests
    $ saxon -it main replace-with-nodes.xsl
    Error on line 49 of ~/tests/replace-with-nodes.xsl:
      XPTY0004: A sequence of more than one item is not allowed
        as the first argument of ati:replace-with-nodes() ("This
        is supposed to be my inpu...", "search1", ...)

        In unidentified location (java.lang.NullPointerException)
        In function ati:replace-specific called from line 100 in
          ~/tests/replace-with-nodes.xsl
        Called from external application
        Called from external application
    Transformation failed: Run-time errors were reported

  Regards,

--drkm

























        

        
                
___________________________________________________________________________ 
Découvrez une nouvelle façon d'obtenir des réponses à toutes vos questions ! 
Profitez des connaissances, des opinions et des expériences des internautes sur 
Yahoo! Questions/Réponses 
http://fr.answers.yahoo.com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--