Click here to Skip to main content
Click here to Skip to main content

Email Template using XSLT and XSLTArgumentList

By , 15 Feb 2005
 

Sample Image

Introduction

This article uses an XSLT file as a template file to store email templates. It specifically targets on usage of Custom Objects Properties to be used in the XSLT file.

Background

Basic knowledge of XML, XPath and XSLT is needed apart from C# and ASP.NET.

Using the code

The Email.cs class in EmailProject can be segregated into various other components to make it as generic as possible. Also, the User.cs and Account.cs class files can be placed in a separate project containing the business objects for the application.

The following are the extracts from the email.cs file:

public static void SetUserDetails()
{
  User myuser = new User();
  myuser.UserName = "ABC";
  myuser.EmailAddress = abc@someemail.com;
  Account myaccount = new Account();
  myaccount.AccountName = "ABC Account";
  Hashtable objHash = new Hashtable();
  objHash["ext:User"] = myuser;
  objHash["ext:Account"] = myaccount;
  SendEmail("xyz@email.com", "emailtemplate.xslt", objHash);
}

The SetUserDetails() function sets the values of User and Account objects. These are objects sent to be used as arguments to the XSLT file. Hence they are added to a HashTable object with the key name as the same as their respective xmlns namespace identifiers in the XSLT file, as shown below.

<?xml version="1.0" encoding="UTF-8" ?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:UserDetails="ext:User"
     xmlns:Account="ext:Account">
XslTransform objxslt = new XslTransform();
objxslt.Load(templatepath + xslttemplatename);
XmlDocument xmldoc = new XmlDocument();
xmldoc.AppendChild(xmldoc.CreateElement("DocumentRoot"));
XPathNavigator xpathnav = xmldoc.CreateNavigator();
XsltArgumentList xslarg = new XsltArgumentList();
if (objDictionary != null)
  foreach (DictionaryEntry entry in objDictionary )
  {
    xslarg.AddExtensionObject(entry.Key.ToString(), entry.Value);
  }
  StringBuilder emailbuilder = new StringBuilder();
  XmlTextWriter xmlwriter = new 
    XmlTextWriter(new System.IO.StringWriter(emailbuilder));
  objxslt.Transform(xpathnav, xslarg, xmlwriter, null);

The above is the code snippet from SendMail method. The arguments to the XslTransform object are added by using the AddExtensionObject method of XsltArgumentlist object.

string subjecttext, bodytext;

XmlDocument xemaildoc = new XmlDocument();
xemaildoc.LoadXml(emailbuilder.ToString());
XmlNode titlenode = xemaildoc.SelectSingleNode("//title");

subjecttext = titlenode.InnerText;

XmlNode bodynode = xemaildoc.SelectSingleNode("//body");

bodytext = bodynode.InnerXml;
if (bodytext.Length > 0)
{
    bodytext = bodytext.Replace("&amp","&");
}

SendEmail(emailto, subjecttext, bodytext);

The above code shows the title text of the XHTML doc to be used as the e-mail's subject and the body text to use used as the body section of the email. This is done by simple XPath.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Mahendra_Nepali
Ireland Ireland
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberrcat11 Apr '11 - 5:15 
Very clever solution
Generalsourcememberkaradas21 Mar '11 - 23:19 
Can you please give me code to implement this wonderfull piece of work.
Thanks in advance.
QuestionHow can I generate multiple table?memberspace257 Nov '06 - 8:29 
Hello
I would like to ask you a question.
I'm trying to create multiple table depending on Order Item count.
for example, if I have order items more than one , it will be
Some For Loop code :

order Number ......
Value 1 ......
 
Please give me some idea..Thanks.
 


GeneralProblem with the href in linkmemberAleBrozzo26 Sep '06 - 18:43 
I do pretty much what you say in your article and example, but using the new mail standar (System.Web.Mail is obsolete and was replaced by System.Net.Mail), and everything works fine except the creation of the link, more specifically, the transformation doesn't add the "href" tag, so the text looks like a link but it's not... I cheked this both in IE 6 and Firefox, and the same thing happens... the "a" tag is rendered like this:
Clik here to activate

 
Why could this be happening? Noone else had this problem?
GeneralRe: Problem with the href in linkmemberMahendra N20 Oct '06 - 4:09 
Can you do a view source on the browser and check if how tag is rendered?
QuestionHow can I check for null attributes of an associated object?memberSG023 Sep '06 - 5:59 
If AccountName is null for some reason, is there a way to check for it within the XSLT?
AnswerRe: How can I check for null attributes of an associated object?memberSG025 Sep '06 - 9:30 
Ok I figured this out, I used MSXSL script and things like this are possible.
Now can somebody please help me with using collection objects as extension objects.
Can I use a generic list as an extension object and then use the
QuestionHow can I access this key and value in the xslt format?memberspacejang1 Aug '06 - 7:14 
emailHash["ext:EmailInfo"] = emaildata;
emailHash["NewPassword"] = this.TemporaryPassword;
======================================================
foreach (DictionaryEntry entry in dictionary)
{
   // Create and add the extension object using AddExtensionObject
   xslarg.AddExtensionObject(entry.Key.ToString(), entry.Value);
}
=========================================================
In the xslt format how can I access "NewPassword"?
<xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:EmailInfo="ext:EmailInfo">
<xsl:param name="NewPassword" />
<xsl:template match="/">
      <html>
          <head>
               <title> Temporary Password </title>
          </head>
      <body>
Your new password is <xsl:value-of select="$NewPassword"/> <br />
E-mail: <xsl:value-of select="EmailInfo:get_FromEmail()" />     
 

</body>
</html>
</xsl:template>
 
</xsl:stylesheet>
AnswerRe: How can I access this key and value in the xslt format?memberMahendra N20 Oct '06 - 4:07 
use can try the AddParam() Method of the XSLTArgumentList Class to supply xslt params and then access them in $ in the XSLT file as you have done.
GeneralAccess properties of Associated Objectsmemberjnapier175 May '06 - 7:09 
Hi, I have used this successfully in multiple sites but I have never figured out how to access child properties of an associated object.
 
Take your sample code for example. What of UserName was an object instead of a string? How would I access the FirstName property of UserName.
 
I have tried this, but it does not work.
 


 
Any ideas?
 
Thanks,
Jesse
Generaltaking one more stepmembery6y6y27 Mar '06 - 15:20 
Hi,
 
This is a great example. But i'm not sure how to pass in an array of objects so I can do a for loop in the xsl. Do you know if this can be done?
GeneralRe: taking one more stepmemberMahendra N29 Mar '06 - 18:11 
ReHi,
I had a thought about this when I had posted the article. But couldn't have any better solution. However there is an alternative approach. U can have a xml serializable model whose XML can be transformed using XSLT and collection nodes can looped using . Let me know if this helps
 

 
Regards
Mahendra
GeneralRe: taking one more step [modified]memberCvetomir Todorov16 Aug '07 - 21:00 
That can surely do.
 
You write your object with all parameters needed for the transformation and you serialize it in XML.
For example:
 
[XmlRoot("mailData")]
public class MailData
{
private string receiverName;
private List receiverBills = new List();
 
[XmlElement("name")]
public string ReceiverName
{
get { return receiverName; }
set { receiverName = value; }
}
 
[XmlArray("bills")]
[XmlArrayItem("bill")]
public List Bills
{
get { return receiverBills; }
}
}
 
If you create it with MailData m = new MailData();
m.ReceiverName = "bob";
m.Bills.Add(5);
m.Bills.Add(10);
 
When you serialize it it will look like:
<?xml version="1.0" ?>
<mailData>
<name>pesho</name>
<bills>
<bill>5</bill>
<bill>10</bill>
</bills>
</mailData>
 
You can then use the XSLCompiledTransform class and call Load to load the XSLT file.
You can call then the Transform method passing it an XmlReader with the serialized mail data
and an XmlWriter to write the output stream which is the result of the transformation.
 
In the XSLT file looping is like this:
<xsl:for-each select="mailData/bills/bill">
<xsl:value-of select="." />
</xsl:for-each>
 
I feel like I am going to write a short article about it though Smile | :)
 

-- modified at 6:18 Friday 17th August, 2007
 
Software modules coupling is the path to the dark side.
Coupling leads to complexity.
Complexity leads to confusion.
Confusion leads to suffering.
Once you start down the dark path, forever will it dominate your destiny, consume you it will!

GeneralRe: taking one more stepmembercbreier11 Jul '06 - 5:14 
Did you ever figure out how to do this? I have the same question.
GeneralRe: taking one more stepmemberthe__turtle11 Jul '06 - 21:52 
Unfortunately not. I just did a quick hack - I added a method to the object i was passing in that looped over the array and formatted a string it as i wanted it.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 16 Feb 2005
Article Copyright 2005 by Mahendra_Nepali
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid