[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Multiple replace() in XSLT 2

Subject: Re: Multiple replace() in XSLT 2
From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 18 May 2019 20:21:46 -0000
Re:  Multiple replace() in XSLT 2
This was an XSLT 1.0 recursive solution:

     https://stackoverflow.com/a/5283744/36305

Based on this algorithm one can produce a non-recursive XSLT 2.0 solution
(and even a single XPath 2 expression).

Here is a first, non-polished but working non-recursive MultiReplace
implementation in XSLT 2.0 -- just 58 lines and  well-formatted. This
implementation also solves the problem of overlapping replacement patterns:

<xsl:stylesheet version="2.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

    <my:params xml:space="preserve">
        <pattern>
          <old>corelation</old>
          <new>dependency</new>
        </pattern>
        <pattern>
          <old>relation</old>
          <new>tie</new>
        </pattern>
        <pattern>
            <old>&#xA;</old>
            <new><br/></new>
        </pattern>
        <pattern>
            <old>quick</old>
            <new>slow</new>
        </pattern>
        <pattern>
            <old>fox</old>
            <new>elephant</new>
        </pattern>
        <pattern>
            <old>brown</old>
            <new>white</new>
        </pattern>
    </my:params>

    <xsl:variable name="vPatterns"
         select="document('')/*/my:params/*"/>

   <xsl:template match="/">
    <xsl:sequence select="my:MultuReplace(/*)"/>
   </xsl:template>

   <xsl:function name="my:MultuReplace">
     <xsl:param name="pText" as="xs:string*"/>

     <xsl:variable name="vStartingIndexes" select=
     "for $ind in 1 to string-length($pText),
          $hasMatchingPattern in
exists($vPatterns[starts-with(substring($pText, $ind), old)])
       return
          $ind[$hasMatchingPattern]
     "/>

     <xsl:variable name="actualIndexes" select=
     "for $ind in $vStartingIndexes
       return $ind
       [position() = 1
       or
         (for $pos in position()[position() > 1],
             $prevInd in $vStartingIndexes[$pos -1],
             $prevReplacementLength in
string-length($vPatterns[starts-with(substring($pText, $prevInd),
old)][1]/old)
          return
             $prevReplacementLength le $ind - $prevInd
         )
       ]
     "/>

     <xsl:variable name="vResultSequence" as="xs:string*">
    <xsl:sequence select=
    "for $pos in  1 to count($actualIndexes),
         $indRepl in $actualIndexes[$pos],
         $startUnprocessedText in
           (if($pos = 1)
              then 1
              else
                (for $indLastReplacedText in $actualIndexes[$pos -1],
                     $last-replacedText in
$vPatterns[starts-with(substring($pText, $indLastReplacedText),
old)][1]/old,
                     $lastReplacementLength in
string-length($last-replacedText)
                    return
                      $actualIndexes[$pos -1] +
string-length($last-replacedText)
                  )
           )
      return
        ( concat(
         substring($pText, $startUnprocessedText, $indRepl -
$startUnprocessedText),
         $vPatterns[starts-with(substring($pText, $indRepl),
old)][1]/new/string()
      )
         )
    "/>

    <xsl:sequence select=
     "for $lastReplIndex in $actualIndexes[last()],
          $last-replacedText in $vPatterns[starts-with(substring($pText,
$lastReplIndex), old)][1]/old,
          $lastReplacementLength in string-length($last-replacedText)
       return
          substring($pText, $lastReplIndex + $lastReplacementLength)
     "/>
      </xsl:variable>

      <xsl:sequence select="string-join($vResultSequence, '')"/>
  </xsl:function>
</xsl:stylesheet>

When this transformation is applied on this source XML document:

<t>a corelation between a quick brown fox and a dog</t>

the wanted result is produced:

*a dependency between a slow white elephant and a dog*



Cheers,
Dimitre


On Thu, May 16, 2019 at 12:49 PM Dimitre Novatchev dnovatchev@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> https://stackoverflow.com/a/5283744/36305
>
> Cheers,
> Dimitre
>
> On Thu, May 16, 2019 at 11:59 AM Rick Quatro rick@xxxxxxxxxxxxxx <
> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>> Hi,
>>
>>
>>
>> I have a look up file of find/change pairs that I have to apply to a text
>> node in my XML document. I am using XSLT 2. Here is an example of the
>> lookup file:
>>
>>
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <findchange_lookup>
>>     <findchange find="Eicas" change="EICAS"/>
>>     <findchange find="Ulb" change="ULB"/>
>> </findchange_lookup>
>>
>> I am reading this in as a global variable, but I am not sure the best
>> approach for doing multiple replacements on the node. I can use recursion
>> like in XSLT 1, but I can't think of how to do this in XSLT 2. There could
>> be any number of <findchange> elements in my lookup file. Any pointers
>> would be appreciated. Thank you very much.
>>
>>
>>
>> Rick
>>
>>
>>
>> Rick Quatro
>>
>> Carmen Publishing Inc.
>>
>> rick@xxxxxxxxxxxxxxx
>>
>> 585-729-6746
>>
>> www.frameexpert.com/store/
>>
>>
>>
>>
>>
>>
>>
>>
>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by
>> email)
>>
>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by
> email <>)
>


-- 
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
To avoid situations in which you might make mistakes may be the
biggest mistake of all
------------------------------------
Quality means doing it right when no one is looking.
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
-------------------------------------
To achieve the impossible dream, try going to sleep.
-------------------------------------
Facts do not cease to exist because they are ignored.
-------------------------------------
Typing monkeys will write all Shakespeare's works in 200yrs.Will they write
all patents, too? :)
-------------------------------------
Sanity is madness put to good use.
-------------------------------------
I finally figured out the only reason to be alive is to enjoy it.

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.