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

级联 XSL

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.40/5 (9投票s)

2004年7月27日

4分钟阅读

viewsIcon

62572

downloadIcon

1130

一个在Web服务器上转换XML文件的引擎。

引言

Layout A Layout B

使用XSL的主要优点是能够轻松地创建和/或更新页面布局。在包含的演示项目中,用“DirTransform.xsl.aspx”替换文件“DirTransform.xsl.aspx”,您将获得一个全新的布局!

ASP.NET使用“用户控件”来保持网站的一致性。ASP.NET 2.0引入了母版-内容页,这是创建模板驱动站点的另一种方式。C-XSL提供了一种替代方法,其中网站文档是XML文件,并且仅包含内容。站点的布局放置在一个单独的XSL文件中。

Using the Code

本文除了C-XSL之外,还介绍了Filters和Modules的使用。该项目包含三个部分:cxslModulecxslFiltercxslProcessor

cxslModule

要安装该模块,我们将以下代码放入Web.config文件的<configuration>/<system.web>部分。

    <httpModules>
            <add name="CXSL::cxslModule" type="CXSL.cxslModule, cxsl" /> 
    </httpModules>

该模块使用以下代码注册两个事件处理程序

    public void Init(HttpApplication application) 
    { 
        application.BeginRequest += 
           (new EventHandler(this.Application_BeginRequest));
        application.PostRequestHandlerExecute += 
           new EventHandler(this.Aplication_PostRequestHandlerExecute);
        return;
    }

当ASP.NET收到请求时,会发生BeginRequest事件。在这里,我们检查用户是否请求了“*.xml.aspx”,如果是,则添加缓冲响应的过滤器。

    private void Application_BeginRequest(Object source, EventArgs e) 
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        if(IsXMLfile(context.Request.FilePath))
        {
            context.Response.Filter = new cxslFilter(context.Response.Filter);
            context.Response.Buffer= true;
        }            
        return;
    }

请求完成并已将响应发送给客户端后,会发生PostRequestHandlerExecute事件。在PostRequestHandlerExecute发生时,Response对象已将结果发送给客户端,并且Response.Output是空的。这就是为什么我们需要过滤器,以便我们可以缓冲输出,并防止它被读取到客户端。

如果请求的是“*.xml.aspx”文件,我们使用过滤器检索页面结果,并使用cxslProcessor类进行转换。最后,我们删除过滤器并将结果返回给客户端。

    private void Aplication_PostRequestHandlerExecute(Object source, 
                                                              EventArgs e) 
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;

        if(IsXMLfile(context.Request.FilePath))
        {        
            //get the buffered output and remove the filter
            String output="";
            context.Response.Clear();

            cxslFilter cFilter=(cxslFilter)context.Response.Filter;
            output=cFilter.GetBuffer();
            context.Response.Filter = cFilter._sink;

            // cascade and return the result
            cxslProcessor cxslProc= new cxslProcessor(application);
            output = cxslProc.fn_Proccess(output);
            context.Response.Write(output);
        }
        return;
    }

cxslFilter

过滤器接收请求的结果,处理它们,然后将它们发送给下一个过滤器。链中的最后一个过滤器将结果发送给客户端。过滤器的典型用法是使公司名称大写,审查不良词语等。在这里,我们以一种不同寻常的方式使用过滤器。它将接收到的所有内容保存在缓冲区中,而不将任何内容发送到下一个过滤器。

下一段代码将过滤器的输入缓存到字符串_outstr中。

    public override void Write(byte[] buffer, int offset, int count)
    {    
        // cache the output into _outstr 
        System.Text.Encoding Enc=System.Text.Encoding.Default;
        _outstr += Enc.GetString(buffer,offset,count);
    }

cxslProcessor

下图展示了C-XSL的逻辑。

C-XSL - Flow

对于每个以.xml.aspx结尾的页面请求,都会初始化该进程。如果存在相应的.xsl.aspx文件,则可能使用该文件转换页面输出。然后,它将输出与General.xml.aspx的结果合并,General.xml.aspx也可能由General.xsl.aspx转换。最后,结果可以由DirTranform.xsl.aspx转换。对于每个父目录,都会重复此操作,直到达到应用程序根目录。

安装和使用演示项目

将文件解压缩到您的/wwwroot/目录中。您现在应该有一个名为/wwwroot/Demo/的目录。或者,您可以在IIS服务器中创建一个名为“Demo”的虚拟目录,指向解压缩后的文件。打开IIS配置控制台,左键单击“/Demo/”,然后选择“属性”。选择“目录”选项卡,然后在“应用程序设置”下,单击“创建”。您现在已经创建了一个应用程序。尝试通过访问“http://yourserver/Demo/Home/Default.xml.aspx”来访问该项目。

演示站点有四个部分,其中2-3部分有两到三个子部分。查看“/Section2/General.xml.aspx”以了解如何以编程方式或通过数据库生成XML。

文件“DirTransform.xsl.aspx”是将站点内容转换为HTML的XSL文件。您可以随意操作它,或者将其替换为“DirTransform.xsl.aspx”以查看结果。

关注点

我必须解决的一个问题是如何合并两个XML文档,因为一个XML文档只能有一个根元素。解决方案是将两者都放入一个<LevelContext>元素中。

一旦我开始使用这个系统,就很清楚没有必要在每个级别都进行转换。使用根目录下的单个DirTransform.xsl.aspx来完成所有转换会更简单。

cxslFilter的工作方式并不完美,并且会导致页面缓存和Viewstate验证问题。我还在努力改进它!

历史

  • C-XSL 1.0 版

    这段代码大约有一年了。我已经在几个站点上使用过它。如果您喜欢这里介绍的想法,您也可以看看nkCMS:C-XSL与CMS系统的结合的后续产品。

相关文章

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.