65.9K
CodeProject 正在变化。 阅读更多。
Home

保存 XML 文件到数据库并使用 XSLT 发送电子邮件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.40/5 (13投票s)

2006年9月14日

CPOL

4分钟阅读

viewsIcon

123298

downloadIcon

1786

从 Web Form 中检索数据到 XML 文件,通过 OPENXML 将数据保存到数据库,然后通过 XSLT 将 XML 转换为 HTML。

引言

在网站中,通常需要一种能力,即通过联系表单将电子邮件发送给组织。根据组织的需要,他们可能需要将此信息保存到数据库,或者直接发送到预定义的电子邮件帐户,以便在此处处理。本文将演示从联系页面检索信息到 XML 文件,使用 XML 文件将数据插入数据库表,然后将 XML 转换为发送到指定帐户所需的格式的基本方法。

背景

通过对 XML 文档执行 XSL 转换,可以将文档转换为所需的任何格式。有许多出色的资源可以帮助您学习 XSLT,因此本文不会深入探讨。我在源代码中也只包含了一些基本的入门知识。包含的 XSL 文件不是 XSL 模板的完美示例,仅仅是足够给您一个如何使用它的概念。利用本文中的信息,您可以轻松地在此基础上进行扩展。

Using the Code

在附带的源代码中,我包含了一个非常简单的数据库,SQL 2000,它由一个表 tblContact 和一个存储过程 spAddContact 组成。该应用程序是用 ASP.NET 2.0 构建的,只有两个页面。我使用了几个 .NET 命名空间。对于本文的目的,最值得注意的是:

  • System.Data.SqlClient
  • System.IO
  • System.Xml
  • System.Xml.Xsl
  • System.Net.Mail
  • System.Text
  • System.IO

步骤 1

单击发送按钮时,我们将创建一个 XML 文件。在示例中,我通过创建内存中的 XML 文件来实现这一点,然后遍历 Page 的控件集合,然后根据控件的类型,将数据追加到 XML 文件中。

注意

作为一种习惯,当我将控件添加到页面时,我坚持使用控件类型的三个字母前缀,例如 DropDownList = ddl。

在遍历控件集合并创建 XML 文件时,我通过对控件 ID 执行 substring(3) 操作来去掉控件类型的三个字母前缀,然后使用剩余的名称部分来创建 XML 标签的名称,并将控件的值放入标签中。

 private XmlDocument GetEmailDocument()
    {
        // We create an xmlDocument with a root node
        XmlDocument xmlDoc = new XmlDocument();
        XmlNode xmlnode;
        xmlnode = xmlDoc.CreateElement("Root");
        xmlDoc.AppendChild(xmlnode);
        GetFormData(pnlEmail, xmlDoc);
        return xmlDoc;
    }

创建了一个非常基本的 XML 文件。GetFormData 方法是一个遍历页面控件集合的方法。GetFormData 方法会检查控件是否可以包含更多控件,如果可能,我们将递归遍历该控件。这是使用递归的一个示例,递归是一个经常被忽视的编程概念。

protected void GetFormData(Control Parent, XmlDocument xmlDoc)
    {
        XmlNode xmlnode;
        foreach (Control wc in Parent.Controls)
        {
        /* Depending on which version of the Framework you are using
       One can choose which version of this line of code you want to use
        for 2.0 You can use if(wc.HasControls())GetFormData(wc, xmlDoc);
        Or alternatively for 1.1 you can count the controls as shown below */

    if (wc.Controls.Count > 0) GetFormData(wc, xmlDoc);
            switch (wc.GetType().FullName.ToString())
            {
                case "System.Web.UI.WebControls.TextBox":
                    TextBox txt = (TextBox)wc;
                    xmlnode = xmlDoc.CreateElement(txt.ID.Substring(3).ToString());
                    xmlnode.InnerText = Server.HtmlEncode(txt.Text);
                    xmlDoc.DocumentElement.AppendChild(xmlnode);
                    break;
                case "System.Web.UI.WebControls.DropDownList":
                    DropDownList ddl = (DropDownList)wc;
                    xmlnode = xmlDoc.CreateElement(ddl.ID.Substring(3).ToString());
                    xmlnode.InnerText = ddl.SelectedValue.ToString();
                    xmlDoc.DocumentElement.AppendChild(xmlnode);
                    break;
            }
        }
    }

第二步

一旦数据被收集到 XML 文件中,我们将把数据保存到数据库。我演示了如何将 XML 文件传递给 SQL Server 2000。执行此操作的 C# 代码没什么特别之处,除了我将 XML 文档作为 SQL 文本传递给 SQL。您可以将此参数作为 CharVarcharnVarcharnText 传递。除了您希望传递的文档大小限制外,这没有区别。我选择将其作为 Text 传递完全是出于习惯(这可能是一个坏习惯 :-))。

 oConn.Open();
           oComm.Connection = oConn;
           oComm.CommandType = CommandType.StoredProcedure;
           oComm.CommandText = "spAddEmailContact";
           oComm.Parameters.Add("@xmlDoc",SqlDbType.Text).Value = 
						xmlDoc.OuterXml.ToString();
          string sRes= oComm.ExecuteScalar().ToString(); 

步骤 3

保存此文件的实际逻辑在 SQL 存储过程中处理。该存储过程有很多实际操作。首先,我们需要将传入参数中的文本转换为内存中的 XML 文件。我们通过使用系统存储过程 sp_xml_preparedocument 来实现这一点,并将 @xmlDoc 作为输入,将 @DocHandle 作为输出,它返回对 XMLDocument 的引用。然后,我们开始了一个看起来像普通的 insert 语句。我们可能接受 XML 文件中的一些空 string。我们不想保存空 string,所以我们只想将其保存为 null。现在我们来到存储过程中稍微复杂的部分,即 OPENXML,我们将前面获得的 Dochandle 传入,然后指定我们想要开始的起始节点。然后,我们将值 2 提供给 XPATH,表示将 XPATH 作为元素进行访问。

ALTER   PROCEDURE dbo.spAddEmailContact

    (
        @xmlDoc text
    )
    
AS
    DECLARE @DocHandle int
    EXEC sp_xml_preparedocument @DocHandle OUTPUT, @xmlDoc

INSERT INTO tblContact
(FirstName, LastName , Email,Street, Town, Postcode,subject, Comment )
    SELECT 
   a.FirstName, 
   a.Lastname ,a.email,
   CASE LTRIM(RTRIM(a.Street))
      WHEN '' THEN NULL 
       ELSE a.Street
   END,
   CASE LTRIM(RTRIM(a.Town))
   WHEN '' THEN NULL
        ELSE a.town
    END ,
    CASE LTRIM(RTRIM(a.Postcode))
    WHEN '' THEN NULL
    ELSE a.Postcode
    END,
    a.subject, a.Comment
FROM OPENXML(@DocHandle, '/Root',2) WITH (FirstName varchar(50), _
	Lastname varchar(50) ,  Email varchar(50), Street varchar(50),
Town varchar(50), Postcode varchar(50),  Subject varchar(50), _
	Comment varchar(250) ) AS a

EXEC sp_xml_removedocument @DocHandle

 Select @@identity
 
    RETURN

步骤 4

现在我们进行 XML/XSLT 转换并发送电子邮件。转换中使用的 XSLT 文件保存在应用程序的 App_Data 文件夹中。我们检索它并利用 XSLCompiledTransform 将 XML 转换为 HTML 文件,然后将其作为电子邮件的正文发送。

private void SendEmail(XmlDocument xmlDoc)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(Server.MapPath("App_Data/email.xsl"));
        using (XmlTextWriter xtw = new XmlTextWriter(new StringWriter(sb)))
         {
            xslt.Transform(xmlDoc, xtw);
            xtw.Flush();
         }
           SmtpClient oMail = new SmtpClient();
           MailMessage msg = new MailMessage();
            try
            {
                MailAddress Madd = new MailAddress(txtEmail.Text, txtFirstName.Text);
                oMail.Host = "localhost";
                oMail.Port = 25;
                msg.From = Madd;
                msg.To.Add("someone@somewhere.com");
                msg.Subject = ddlSubject.SelectedValue.ToString();
                msg.IsBodyHtml = true;
                msg.Body = sb.ToString();
                oMail.Send(msg);
                Server.Transfer("sent.aspx");
            }
            catch (Exception ex)
            {
                //This step is not good practice but seen as though this is just a Demo
                //app I thought I would place this here so we can see if any errors occur
                lblFail.Visible = true;
                lblFail.Text = "An Error occurred:" + ex.Message;
            }   
    }

历史

  • 14-09-06 首次上传,打算稍后更新文章
© . All rights reserved.