Written by

Question Paul Beckett · Jun 16, 2016

Applying string functions ($replace, $zconvert etc) to a %Library.GlobalCharacterStream

Hi,

I have a bit of code that does a find and replace on a "template" and inserts additional content. For example it replaces the @DATA@ with an html table:

<html>

   <body>

      <div id="data">@DATA@</div>

   </body>

</html>

Currently doing this with the $replace function:

Set text=$replace(text, "@DATA@", data)

The problem is the "data" is now too big for a %String (yes even with large strings) so will switch to use a stream instead. 

Is there an equivalent to $replace that works on a stream? If not, how would I best implement this sort of find/replace functionality in cache object script? Note: this is back end functionality that creating an html report that will be sent out via a soap webservice. It is not using zen.

thanks

Paul

Comments

Eduard Lebedyuk · Jun 16, 2016

If data is too big for a string then result would also be too big for a string.

 I think something like this would work:

  1. Create result stream
  2. Find positions of the beginning and the end of the first placeholder in the template
  3. Write template from the start to the beginning of the first placeholder
  4. Copy data stream into  result stream
  5. Repeat 2-4 till you have no more placeholders (if there's more than one placeholder per template)
  6. Send result stream out via a soap webservice

It can be done as one method with this signature ( so it would be possible to pass any number of data streams for one template):

ClassMethod FillTemplate(Template As %String, Data... As %Stream.GlobalCharacter) As %Stream.GlobalCharacter {}
0
Jon Willeke  Jun 16, 2016 to Eduard Lebedyuk

In general, no, you can't apply string functions directly to streams. I found one such enhancement request from eight years ago that has since been closed. (There may have been others.)

For the specific case of $replace, it should be straightforward to implement Eduard's suggestion using the FindAt() method.

0
Eduard Lebedyuk  Jun 16, 2016 to Jon Willeke

Template is most probably a string, so the usual $find would work.

0
Paul Beckett  Jun 18, 2016 to Jon Willeke

thanks for your help. I implemented my replace using the FindAt method of the stream. Main reason was to allow repeat passes over the template when there are multiple tokens to replace.

0
Christopher Henson  May 7, 2020 to Paul Beckett

Hi Paul, do you happen to have your final solution.  I'm working on something similar and am struggling to get it functioning correctly..

0