Improving multiple find / replace on HTML string

I'm trying to write some code that will be used for making HTML emails.  The problem is that the code seems to be very, very inefficient and I'd like to improve it if possible.  The code below reads a HTML file into a string then runs a number of string.replace() functions to get the correct output.  This is a very stripped down version of what I have:

      Dim sr As System.IO.StreamReader = New System.IO.StreamReader("htmlfile.htm")
      Dim s As String = sr.ReadToEnd

      s = s.Replace("##Date##", "Date value")
      s = s.Replace("##ADDRESS##", "Address value")


Below is an example of the HTML in the file (Sorry, I know this bit is a little obvious)

      <table>
      <tr>
            <td>
                  Date
            </td>
            <td>
                  ##DATE##
            </td>
      </tr>
      <tr>
            <td>
                  Address
            </td>
            <td>
                  ##ADDRESS##
            </td>
      </tr>
      </table>
      
In my code I'm running s = s.replace() more than 10 times, and given this reads the entire string, modifies it and then writes it again I'm thinking it can't be the best way of doing it.  Can anyone think of any way that I can do all of the replacements in one go or improve the code in any way?

Thanks in advance.
LVL 2
PsychotextAsked:
Who is Participating?
 
Timbo87Connect With a Mentor Commented:
You could also do something like this:

using System.Text;

string[] oldVal = new string[]{"##DATE##", "##ADDRESS##"};
string[] newVal = new string[]{DateTime.Now.ToString(), "123 Main Street"};

StringBuilder sb = new StringBuilder(htmlString);
for(int i = 0; i < oldVal.Length; i++)
      sb.Replace(oldVal[i], newVal[i]);

Response.Write("The new HTML " + sb.ToString());
0
 
Timbo87Commented:
Using a StringBuilder would most likely improve performance.

using System.Text;

StringBuilder sb = new StringBuilder("initial value");
sb.Replace("1", "a");
sb.Replace("2", "b");
0
 
PsychotextAuthor Commented:
Thanks for that.  I'll run some tests to see how it works out performance wise.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
nauman_ahmedConnect With a Mentor Commented:
That seems to be a hardway of reading text for e-mail. Why dont you just hard code the text and get rid of the difficulty. If you want this to be more complicated :p, you can embed your string in resource file and then read from there:

Its not a complete code. Just an idea on how you can make it easier if you do not change your e-mail text very often:

StringBuilder sb = new StringBuilder();
sb.Append("Dear "+strUserName+"\r\n");
sb.Append("Text...........\r\n");
sb.Append("Some more text \r\n");
sb.Append("Thank you\r\n");
sb.Append("Support");

myMailMessage.Body = sb.ToString();
SmtpMail.Send(myMailMessage);

HTH, Nauman.
0
 
mmarinovConnect With a Mentor Commented:
Hi Psychotext,

you can inprove the performance if you use Regular expressions, like

s = Regex.Replace(s, "##DATE##", "Date value" )
s = Regex.Replace(s, "##ADDRESS##", "Address value")


Regards!
B..M
0
 
PsychotextAuthor Commented:
nauman:  That's the way I would normally do it, but the client wants the ability to edit their own HTML files to use as a template for the HTML emails.  It'll all end in tears... ;-)
0
 
PsychotextAuthor Commented:
Ok, testing complete.  What I did is set each way of doing it up in a sub and call the sub 500 times.  Times are taken from the trace page.  For fun I included the Nauman's HTML from scratch method too.  I was a little suprised by some of the results so I gave it all a second run (Times shown in brackets):

Initial Code (Mine):
      Run 1:      1.683910 (1.783089)
      Run 2:      1.692010 (1.758817)
      Run 3:      1.682849 (1.709526)
      Run 4:      1.717491 (1.701330)
      Run 5:      1.687957 (1.690669)
      
      AVERAGE:      1.6928434 (1.7286862)

      
Regex Code (mmarinov):
      Run 1:      1.688086 (1.736237)
      Run 2:      1.689304 (1.997267)
      Run 3:      1.640872 (1.745414)
      Run 4:      1.648548 (1.732736)
      Run 5:      1.654695 (1.714441)
            
      AVERAGE:      1.6643010 (1.785219)


String Builder (timbo87 - Post 1):
      Run 1:      1.451863 (1.419885)
      Run 2:      1.386998 (1.396693)
      Run 3:      1.393115 (1.399178)
      Run 4:      1.385554 (1.398820)
      Run 5:      1.435610 (1.401689)
      
      AVERAGE:      1.4106280 (1.403253)


Old & New (timbo87 - Post 2):
      Run 1:      1.446688 (1.420638)
      Run 2:      1.385504 (1.399974)
      Run 3:      1.386387 (1.408367)
      Run 4:      1.386811 (1.439679)
      Run 5:      1.394764 (1.395636)
      
      AVERAGE:      1.4000308 (1.4128588)

      
HTML From Scratch (Nauman_ahmed):
      Run 1:      0.171699 (0.171120)
      Run 2:      0.122329 (0.122359)
      Run 3:      0.123531 (0.124216)
      Run 4:      0.125959 (0.126573)
      Run 5:      0.123910 (0.123147)
            
      AVERAGE:      0.1334856 (0.133483)

Not a lot to call between Timbo's methods.  They both shave some time off the prodedure.   Looks like the main bottleneck (Unsurprisingly) is actually getting the file off the disk for reading.  This is fairly well demonstrated by Nauman's method and the fact it's over 10x faster than the others.

I think I may cache the file in memory until it changes on the disk; should speed things up a fair bit.
0
 
nauman_ahmedCommented:
Experts, what do you think if Psychotext creates a user control, add the HTML, and where it is needed to put the dynamically generated data, create server controls e.g. Label etc. The HTML can be grabbed from the user control easily. In the past, Aeros posted some code to get the HTML but I couldnt find that link. Will this way be little easier?

Best, nauman.
0
 
nauman_ahmedCommented:
Got the link:

URL: http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/ASP_DOT_NET/Q_21146312.html?query=table+html&topics=865

Table innerTable = new Table();
  Table mainTable = new Table();
  mainTable.Rows.Add(new TableRow());
  mainTable.Rows.Add(new TableRow());
  mainTable.Rows[0].Cells.Add( new TableCell());
  mainTable.Rows[0].Cells[0].Controls.Add(innerTable);


  System.IO.StringWriter sw = new System.IO.StringWriter();
  HtmlTextWriter htmltw = new HtmlTextWriter(sw);
  mainTable.RenderControl(htmltw);
 
  String strHTML = sw.ToString();

Any ideas on how we can grab the HTML from the user control?

-Nauman.
0
 
PsychotextAuthor Commented:
To be fair I've split the points awarded for this post as everyone helped toward the answer.
0
All Courses

From novice to tech pro — start learning today.