Using XSLT for sending emails

G

Guest

I am working on a website for a client and one of their requirements was to
have a mailing list. I decided to XSLT to transform "templates" to HTML so
that editing was very easy and less time consuming. I keep getting the
following error when I submit my email to their site.

System.Xml.Xsl.XslTransformException: Cannot find the script or external
object that implements prefix 'ext:MailingList'. at
System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String
name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at Root(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at Execute(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at
System.Xml.Xsl.ExecuteDelegate.Invoke(XmlQueryRuntime runtime) at
System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver
dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) at
System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver
dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean
closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable
contextDocument, XmlResolver dataSources, XsltArgumentList argumentList,
XmlWriter results) at
System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input,
XsltArgumentList arguments, XmlWriter results) at
BusinessLogic.EmailTemplate.SendEmailMessage(String emailTo, String
xslTemplate, IDictionary dictionary) at
BusinessLogic.MailingList.SendMailingListVerification() at
BusinessLogic.MailingList.Add() at _Default.cmdSubmitEmail_Click(Object
sender, ImageClickEventArgs e)
at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String
name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at Root(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at Execute(XmlQueryRuntime
{urn:schemas-microsoft-com:xslt-debug}runtime) at
System.Xml.Xsl.ExecuteDelegate.Invoke(XmlQueryRuntime runtime) at
System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver
dataSources, XsltArgumentList argumentList, XmlSequenceWriter results) at
System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver
dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean
closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable
contextDocument, XmlResolver dataSources, XsltArgumentList argumentList,
XmlWriter results) at
System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input,
XsltArgumentList arguments, XmlWriter results) at
BusinessLogic.EmailTemplate.SendEmailMessage(String emailTo, String
xslTemplate, IDictionary dictionary) at
BusinessLogic.MailingList.SendMailingListVerification() at
BusinessLogic.MailingList.Add() at _Default.cmdSubmitEmail_Click(Object
sender, ImageClickEventArgs e)

Here is my XSLT file:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:MailingList="ext:MailingList">
<xsl:template match="/">
<html>
<head>
<title>The SomeSite Campaign</title>
</head>
<body>
<P>
Thank you for your interest in the The SomeSite Campaign,
</P>
In order for you to receive emails from our mailing list, you must
first confirm your email address by clicking on the link below.<BR />
<a>
<xsl:attribute name="href">

http://www.somesite.com/subscriptions/ConfirmMailing.aspx?email=<xsl:value-of
select="MailingList:Email()" />&validation=

</xsl:attribute>http://www.SomeSite.com/subscriptions/ConfirmMailing.aspx?email=<xsl:value-of select="MailingList:Email()" />&validation=
</a>
<P>
Regards,
The SomeSite Campaign
</P>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

If I take out <xsl:value-of select="MailingList:Email()" /> statements an
email is generated and sent, but it just contains HTML. Here is my mailing
list class in which there is a email address and verification hash.

Imports Microsoft.VisualBasic

Namespace BusinessLogic

Public Class MailingList
Inherits BusinessLogic.DataAccessBase

Private pEmail As String
Private pHash As String

Public Property Email() As String
Get
Return pEmail
End Get
Set(ByVal value As String)
If Validation.ValidateEmail(value) = False Then Throw New
Exception(Resources.StringResources.EmailAddressInvalidFormat)
pEmail = value
End Set
End Property

Public Property Hash() As String
Get
Return pHash
End Get
Set(ByVal value As String)
pHash = value
End Set
End Property

Public Sub New(ByVal email As String, ByVal hash As String)
Me.Email = email
Me.Hash = hash
End Sub

Public Sub New()
End Sub

''' <summary>
''' Adds a new email address to the mailing list.
''' </summary>
Public Sub Add()
Dim dbConn As DataAccess.DataAccessBase =
DataAccess.DataAccessBaseHelper.GetDataAccessLayer
Dim pr As DataAccess.DataAccessBase.ProcedureResults
pr = dbConn.AddMailingList(pEmail, pHash)

Me.pErrorCode = pr.ErrorCode
Me.pRowCount = pr.RowCount

SendMailingListVerification()
End Sub

''' <summary>
''' Verifies an email address and marks it as valid.
''' </summary>
Public Sub Verify()
Dim dbConn As DataAccess.DataAccessBase =
DataAccess.DataAccessBaseHelper.GetDataAccessLayer
Dim pr As DataAccess.DataAccessBase.ProcedureResults
pr = dbConn.VerifyMailingList(pEmail, pHash)

Me.pErrorCode = pr.ErrorCode
Me.pRowCount = pr.RowCount
End Sub

''' <summary>
''' Removes an email address from the mailing list after validating
that it exists.
''' </summary>
Public Sub Delete()
Dim dbConn As DataAccess.DataAccessBase =
DataAccess.DataAccessBaseHelper.GetDataAccessLayer
Dim pr As DataAccess.DataAccessBase.ProcedureResults
pr = dbConn.DeleteMailingList(pEmail, pHash)

Me.pErrorCode = pr.ErrorCode
Me.pRowCount = pr.RowCount
End Sub

Private Sub SendMailingListVerification()
Dim hashTbl As New Hashtable
hashTbl("ext:List") = Me

EmailTemplate.SendEmailMessage(pEmail,
System.Web.HttpContext.Current.Server.MapPath("~/public/templates/AddMailingList.xslt"), hashTbl)
End Sub

End Class

End Namespace

Finally, here is my email class in which I am trying to insert my data into
the XSLT file so that I can send it.

Imports Microsoft.VisualBasic
Imports System.Collections
Imports System.Xml
Imports System.Xml.Xsl
Imports System.Xml.XPath
Imports System.Text
Imports System.Net.Mail

Namespace BusinessLogic

Public Class EmailTemplate

Public Shared Sub SendEmailMessage(ByVal emailTo As String, ByVal
xslTemplate As String, ByVal dictionary As IDictionary)

Dim objXSLT As New XslCompiledTransform
objXSLT.Load(xslTemplate)

Dim xmlDoc As New XmlDocument
xmlDoc.AppendChild(xmlDoc.CreateElement("DocumentRoot"))
Dim xPathNav As XPathNavigator = xmlDoc.CreateNavigator

Dim xslArg As New XsltArgumentList
If dictionary IsNot Nothing Then
For Each entry As DictionaryEntry In dictionary
xslArg.AddExtensionObject(entry.Key.ToString, entry.Value)
Next
End If

Dim emlBuilder As New StringBuilder
Dim xmlWriter As New XmlTextWriter(New
System.IO.StringWriter(emlBuilder))

objXSLT.Transform(xPathNav, xslArg, xmlWriter)

Dim subjText As String
Dim bodyText As String

Dim xEmailDoc As New XmlDocument
xEmailDoc.LoadXml(emlBuilder.ToString)
Dim titleNode As XmlNode = xEmailDoc.SelectSingleNode("//title")

subjText = titleNode.InnerText

Dim bodynode As XmlNode = xEmailDoc.SelectSingleNode("//body")

bodyText = bodynode.InnerXml
If bodyText.Length > 0 Then
bodyText = bodyText.Replace("&", "&")
End If

Dim oMail As New MailMessage(Configuration.SMTPSender, emailTo)
oMail.Subject = subjText
oMail.Body = bodyText
oMail.BodyEncoding = Encoding.UTF8
oMail.IsBodyHtml = True

Dim oSMTP As New SmtpClient(Configuration.SMTPServer)
oSMTP.Credentials = New
System.Net.NetworkCredential(Configuration.SMTPUserName,
Configuration.SMTPPassword)
oSMTP.Send(oMail)
End Sub

End Class

End Namespace

I saw some examples of people using dictionary or hash table objects to
contain their data so that they only needed on so-called template parser. I
am trying to do the same as I will have 10-15 different templates when the
site is finished. Thanks for any help.

- Nick
 
M

Michael Nemtsev

Hello Nick,

And where is your "ext" namespace declaration? You need specify it, the error
point exactly on it

N> I am working on a website for a client and one of their requirements
N> was to have a mailing list. I decided to XSLT to transform
N> "templates" to HTML so that editing was very easy and less time
N> consuming. I keep getting the following error when I submit my email
N> to their site.
N>
N> System.Xml.Xsl.XslTransformException: Cannot find the script or
N> external
N> object that implements prefix 'ext:MailingList'. at
N> System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(St
N> ring
N> name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> Root(XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> Execute(XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> System.Xml.Xsl.ExecuteDelegate.Invoke(XmlQueryRuntime runtime) at
N> System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument,
N> XmlResolver
N> dataSources, XsltArgumentList argumentList, XmlSequenceWriter
N> results) at
N> System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument,
N> XmlResolver
N> dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean
N> closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable
N> contextDocument, XmlResolver dataSources, XsltArgumentList
N> argumentList,
N> XmlWriter results) at
N> System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input,
N> XsltArgumentList arguments, XmlWriter results) at
N> BusinessLogic.EmailTemplate.SendEmailMessage(String emailTo, String
N> xslTemplate, IDictionary dictionary) at
N> BusinessLogic.MailingList.SendMailingListVerification() at
N> BusinessLogic.MailingList.Add() at
N> _Default.cmdSubmitEmail_Click(Object
N> sender, ImageClickEventArgs e)
N> at
N> System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(St
N> ring
N> name, String namespaceUri, IList`1[] args) at (XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> Root(XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> Execute(XmlQueryRuntime
N> {urn:schemas-microsoft-com:xslt-debug}runtime) at
N> System.Xml.Xsl.ExecuteDelegate.Invoke(XmlQueryRuntime runtime) at
N> System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument,
N> XmlResolver
N> dataSources, XsltArgumentList argumentList, XmlSequenceWriter
N> results) at
N> System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument,
N> XmlResolver
N> dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean
N> closeWriter) at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable
N> contextDocument, XmlResolver dataSources, XsltArgumentList
N> argumentList,
N> XmlWriter results) at
N> System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input,
N> XsltArgumentList arguments, XmlWriter results) at
N> BusinessLogic.EmailTemplate.SendEmailMessage(String emailTo, String
N> xslTemplate, IDictionary dictionary) at
N> BusinessLogic.MailingList.SendMailingListVerification() at
N> BusinessLogic.MailingList.Add() at
N> _Default.cmdSubmitEmail_Click(Object
N> sender, ImageClickEventArgs e)
N> Here is my XSLT file:
N>
N> <?xml version="1.0" encoding="UTF-8" ?>
N> <xsl:stylesheet version="1.0"
N> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
N> xmlns:MailingList="ext:MailingList">
N> <xsl:template match="/">
N> <html>
N> <head>
N> <title>The SomeSite Campaign</title>
N> </head>
N> <body>
N> <P>
N> Thank you for your interest in the The SomeSite Campaign,
N> </P>
N> In order for you to receive emails from our mailing list, you
N> must
N> first confirm your email address by clicking on the link below.<BR />
N> <a>
N> <xsl:attribute name="href">
N> http://www.somesite.com/subscriptions/ConfirmMailing.aspx?email=<xsl:
N> value-of select="MailingList:Email()" />&validation=
N>
N> </xsl:attribute>http://www.SomeSite.com/subscriptions/ConfirmMailing.
N> aspx?email=<xsl:value-of select="MailingList:Email()" />&validation=
N> </a>
N> <P>
N> Regards,
N> The SomeSite Campaign
N> </P>
N> </body>
N> </html>
N> </xsl:template>
N> </xsl:stylesheet>
N>
N> If I take out <xsl:value-of select="MailingList:Email()" />
N> statements an email is generated and sent, but it just contains HTML.
N> Here is my mailing list class in which there is a email address and
N> verification hash.
N>
N> Imports Microsoft.VisualBasic
N>
N> Namespace BusinessLogic
N>
N> Public Class MailingList
N> Inherits BusinessLogic.DataAccessBase
N> Private pEmail As String
N> Private pHash As String
N> Public Property Email() As String
N> Get
N> Return pEmail
N> End Get
N> Set(ByVal value As String)
N> If Validation.ValidateEmail(value) = False Then Throw
N> New
N> Exception(Resources.StringResources.EmailAddressInvalidFormat)
N> pEmail = value
N> End Set
N> End Property
N> Public Property Hash() As String
N> Get
N> Return pHash
N> End Get
N> Set(ByVal value As String)
N> pHash = value
N> End Set
N> End Property
N> Public Sub New(ByVal email As String, ByVal hash As String)
N> Me.Email = email
N> Me.Hash = hash
N> End Sub
N> Public Sub New()
N> End Sub
N> ''' <summary>
N> ''' Adds a new email address to the mailing list.
N> ''' </summary>
N> Public Sub Add()
N> Dim dbConn As DataAccess.DataAccessBase =
N> DataAccess.DataAccessBaseHelper.GetDataAccessLayer
N> Dim pr As DataAccess.DataAccessBase.ProcedureResults
N> pr = dbConn.AddMailingList(pEmail, pHash)
N> Me.pErrorCode = pr.ErrorCode
N> Me.pRowCount = pr.RowCount
N> SendMailingListVerification()
N> End Sub
N> ''' <summary>
N> ''' Verifies an email address and marks it as valid.
N> ''' </summary>
N> Public Sub Verify()
N> Dim dbConn As DataAccess.DataAccessBase =
N> DataAccess.DataAccessBaseHelper.GetDataAccessLayer
N> Dim pr As DataAccess.DataAccessBase.ProcedureResults
N> pr = dbConn.VerifyMailingList(pEmail, pHash)
N> Me.pErrorCode = pr.ErrorCode
N> Me.pRowCount = pr.RowCount
N> End Sub
N> ''' <summary>
N> ''' Removes an email address from the mailing list after
N> validating
N> that it exists.
N> ''' </summary>
N> Public Sub Delete()
N> Dim dbConn As DataAccess.DataAccessBase =
N> DataAccess.DataAccessBaseHelper.GetDataAccessLayer
N> Dim pr As DataAccess.DataAccessBase.ProcedureResults
N> pr = dbConn.DeleteMailingList(pEmail, pHash)
N> Me.pErrorCode = pr.ErrorCode
N> Me.pRowCount = pr.RowCount
N> End Sub
N> Private Sub SendMailingListVerification()
N> Dim hashTbl As New Hashtable
N> hashTbl("ext:List") = Me
N> EmailTemplate.SendEmailMessage(pEmail,
N> System.Web.HttpContext.Current.Server.MapPath("~/public/templates/Add
N> MailingList.xslt"), hashTbl)
N> End Sub
N> End Class
N>
N> End Namespace
N>
N> Finally, here is my email class in which I am trying to insert my
N> data into the XSLT file so that I can send it.
N>
N> Imports Microsoft.VisualBasic
N> Imports System.Collections
N> Imports System.Xml
N> Imports System.Xml.Xsl
N> Imports System.Xml.XPath
N> Imports System.Text
N> Imports System.Net.Mail
N> Namespace BusinessLogic
N>
N> Public Class EmailTemplate
N>
N> Public Shared Sub SendEmailMessage(ByVal emailTo As String,
N> ByVal xslTemplate As String, ByVal dictionary As IDictionary)
N>
N> Dim objXSLT As New XslCompiledTransform
N> objXSLT.Load(xslTemplate)
N> Dim xmlDoc As New XmlDocument
N> xmlDoc.AppendChild(xmlDoc.CreateElement("DocumentRoot"))
N> Dim xPathNav As XPathNavigator = xmlDoc.CreateNavigator
N> Dim xslArg As New XsltArgumentList
N> If dictionary IsNot Nothing Then
N> For Each entry As DictionaryEntry In dictionary
N> xslArg.AddExtensionObject(entry.Key.ToString,
N> entry.Value)
N> Next
N> End If
N> Dim emlBuilder As New StringBuilder
N> Dim xmlWriter As New XmlTextWriter(New
N> System.IO.StringWriter(emlBuilder))
N> objXSLT.Transform(xPathNav, xslArg, xmlWriter)
N>
N> Dim subjText As String
N> Dim bodyText As String
N> Dim xEmailDoc As New XmlDocument
N> xEmailDoc.LoadXml(emlBuilder.ToString)
N> Dim titleNode As XmlNode =
N> xEmailDoc.SelectSingleNode("//title")
N> subjText = titleNode.InnerText
N>
N> Dim bodynode As XmlNode =
N> xEmailDoc.SelectSingleNode("//body")
N>
N> bodyText = bodynode.InnerXml
N> If bodyText.Length > 0 Then
N> bodyText = bodyText.Replace("&", "&")
N> End If
N> Dim oMail As New MailMessage(Configuration.SMTPSender,
N> emailTo)
N> oMail.Subject = subjText
N> oMail.Body = bodyText
N> oMail.BodyEncoding = Encoding.UTF8
N> oMail.IsBodyHtml = True
N> Dim oSMTP As New SmtpClient(Configuration.SMTPServer)
N> oSMTP.Credentials = New
N> System.Net.NetworkCredential(Configuration.SMTPUserName,
N> Configuration.SMTPPassword)
N> oSMTP.Send(oMail)
N> End Sub
N> End Class
N>
N> End Namespace
N>
N> I saw some examples of people using dictionary or hash table objects
N> to contain their data so that they only needed on so-called template
N> parser. I am trying to do the same as I will have 10-15 different
N> templates when the site is finished. Thanks for any help.
N>
N> - Nick
N>
---
WBR,
Michael Nemtsev :: blog: http://spaces.msn.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top