在SQL Server 2005中使用xml类型存储XSLT?

8

我在我的ASP.NET网站中有很多XSL文件。非常多。我使用这种通用的转换方法生成一堆AJAX HTML响应:

public void Transform(XmlDocument xml, string xslPath) 
{
    ...
    XslTransform myXslTrans = new XslTransform();
    myXslTrans.Load(xslPath);
    myXslTrans.Transform(xml,null, HttpContext.Current.Response.Output);        
}

我希望将XSL定义移入SQL Server,使用xml类型的列。我会在SQL中将整个XSL文件存储在单个行中,并且每个XSL都是自包含的(没有导入)。我将从SQL中读取XSL定义到我的XslTransform对象中。
类似这样:
public void Transform(XmlDocument xml, string xslKey) 
{
    ...

    SqlCommand cmd = new SqlCommand("GetXslDefinition");
    cmd.AddParameter("@xslKey", SqlDbType.VarChar).Value = xslKey;
    // where the result set has a single column of XSL: "<xslt:stylesheet>..." 
    ...

    SqlDataReader dr = cmd.ExecuteReader();
    if(dr.Read()) {
        SqlXml xsl = dr.GetSqlXml(0);
        XslTransform myXslTrans = new XslTransform();
        myXslTrans.Load(xsl.CreateReader());
        myXslTrans.Transform(xml,null, HttpContext.Current.Response.Output);     
    }   
}

似乎有一种简单的方法可以实现以下目标:
  • 为每个XSL添加元数据,如lastUsed、useCount等;
  • 批量更新/搜索功能;
  • 避免大量磁盘访问;
  • 避免相对路径引用和文件组织;
  • 允许更改XSL而无需重新部署(甚至可以编写一个管理页面,在数据库中选择/更新XSL)。
有人尝试过这种方法吗?有什么需要注意的地方吗? 编辑 回答者列出的注意事项如下:
  • 磁盘访问不一定会减少;
  • 这将破坏xsl:includes。
2个回答

3

我在我的应用程序dbscript中将XSLT存储在数据库中。(但是由于它也运行在SQL Server 2000上,我将它们保存在NVARCHAR列中)

由于用户能够编辑他们的XSLT,我需要编写一个自定义验证器,将TextBox的文本加载到.Net XslCompiledTransform对象中,如下所示:

    args.IsValid = true;

    if (args.Value.Trim() == "")
        return;

    try
    {
        System.IO.TextReader rd = new System.IO.StringReader(args.Value);
        System.Xml.XmlReader xrd = System.Xml.XmlReader.Create(rd);
        System.Xml.Xsl.XslCompiledTransform xslt = new System.Xml.Xsl.XslCompiledTransform();
        System.Xml.Xsl.XsltSettings xslts = new System.Xml.Xsl.XsltSettings(false, false);
        xslt.Load(xrd, xslts, new System.Xml.XmlUrlResolver());
        xrd.Close();
    }
    catch (Exception ex)
    {
        this.ErrorMessage = (string.IsNullOrEmpty(sErrorMessage) ? "" : (sErrorMessage + "<br/>") +
            ex.Message);
        if (ex.InnerException != null)
        {
            ex = ex.InnerException;
            this.ErrorMessage += "<br />" + ex.Message;
        }
        args.IsValid = false;
    }

关于你的观点:
  • 文件I/O将被数据库生成的磁盘I/O所取代,因此没有任何收益

  • 部署更改为提供包含新数据的INSERT/UPDATE脚本


谢谢!验证XSLT的好例子。在性能方面,您是否真正经历了磁盘I/O的增加?我需要进行一些测试,但我印象中SQL Server可以利用相当大的内存数据缓存。 - Jeff Meatball Yang

3
我能看到的两个主要问题是:
  1. 我们使用许多包含文件来确保我们只做一次事情,将XSLT存储在数据库中会阻止我们这样做。
  2. 更新XSLs将变得更加有趣 - 我们很乐意将新的.xsl文件放入已部署的站点中,而不进行完整的网站更新。就此而言,我们有一些代码片段,在文件夹中查找客户端特定xsl,并且这些代码片段可以返回到根目录中的公共代码(模板)- 因此我对重新部署一事并不确定,但这将非常依赖于特定用例,您的用例肯定与我们的不同。

就磁盘访问而言,嗯...数据库仍然需要访问磁盘以提取数据,并且如果您谈论缓存,则数据库不是启用缓存的要求。

我同意关于更新/搜索选项的观点 - 您可以使用PowerShell来处理,但需要在服务器上运行,这并不总是一个好主意。

技术上来说,我没有看到任何理由不这样做(除了如上所述的包含愿望),但实际上它似乎相当平衡,双方都有充分的论据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接