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

Cascade XSL

, 29 Dec 2004
Rate this:
Please Sign up or sign in to vote.
An engine that transforms XML files on a web server.

Introduction

Layout A Layout B

The major advantage of using XSL is the ease with which you can create and/or update a page layout. In the included demo project, replace the file 'DirTransform.xsl.aspx' by the 'DirTransform.xsl.aspx' and you have a completely new layout!

The ASP.NET uses 'user controls' for adding consistency to a web site. Version 2.0 of ASP.NET introduces master-content pages which is yet another way for creating a template driven site. C-XSL provides an alternative way, where the documents of a website are XML files and contain only the content. The layout of the site is placed in a separate XSL file.

Using the code

This article apart from C-XSL, it presents the use of Filters and Modules. The project consists of three parts, cxslModule, cxslFilter, and cxslProcessor.

cxslModule

To install the module, we put the following code in the <configuration>/<system.web> section of Web.config file.

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

The Module registers two event handlers using the following code:

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

The BeginRequest event occurs when ASP.NET receives a request. Here, we check if the user requests an *.xml.aspx, and if so, we add the filter which buffers the response.

    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;
    }

The PostRequestHandlerExecute event occurs when the request is finished and the response has been send to the client. At the time PostRequestHandlerExecute occurs, the Response object has already sent the result to the client and the Response.Output is clear. That's why we need the filter, so we can buffer the output, and prevent it from reading the client.

If the request was for an *.xml.aspx file, we use the filter to retrieve the result of the page, and use the cxslProcessor class to do the transformation. Finally, we remove the filter and return the result to the client.

    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

A filter receives the results of a request, processes them, and then sends them to the next filter. The last filter in the chain sends the result to the client. A typical use of a filter is to make uppercase the word of a company, censor bad words, etc. Here, we use a filter in an odd way. It keeps everything it receives in a buffer and sends nothing to the next filter.

The next piece of code caches the input of the filter in the string _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

The following diagram presents the logic of C-XSL.

C-XSL - Flow

The process is initialized for every request of pages ending in .xml.aspx. The output of the page might be transformed using the corresponding .xsl.aspx file, if it exists. Then, it merges the output with the result of General.xml.aspx which also might be transformed by General.xsl.aspx. Finally, the result can be transformed by DirTranform.xsl.aspx. That is repeated for every parent directory till it reaches the application root.

Installing and using the demo project

Unzip the files inside your /wwwroot/ directory. You should now have a directory called /wwwroot/Demo/. Alternatively, you may create a virtual directory in your IIS server named 'Demo' that points to the unzipped files. Open the IIS configuration console, left-click on '/Demo/' and select Properties. Select the tab 'Directories', and on the 'Applications Settings', click Create. You have now created an application. Try accessing the project by visiting 'http://yourserver/Demo/Home/Default.xml.aspx'.

The demo site has four sections where sections 2-3 has two or more subsections. Check out '/Section2/General.xml.aspx' to see how you can generate XML programmatically or through a database.

The file 'DirTransform.xsl.aspx' is the XSL file that transforms the content of the site into HTML. Play around with it or replace it with 'DirTransform.xsl.aspx' to see the result.

Points of Interest

One problem I had to solve was how to merge two XML documents since an XML document must have only one root element. The solution was to put both inside a <LevelContext> element.

Once I started using this system, it became clear that there is no need to do transformations at every level. It's simpler to use a single DirTransform.xsl.aspx at the root to do all the transformations.

The way cxslFilter works is not perfect and causes problems with page caching and Viewstate validation. I am still working on it!

History

  • C-XSL version 1.0

    This code is about a year old. I have used it on a couple of sites. If you like the ideas presented here, you could also take a look at nkCMS: the successor of C-XSL combined with a CMS system.

Related Articles

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

Kastellanos Nikos
Founder tainicom
Greece Greece
No Biography provided
Follow on   Twitter

Comments and Discussions

 
GeneralMissing Source Code PinmemberTony Bermudez27-Jul-04 8:08 
GeneralRe: Missing Source Code PinmemberKastellanos Nikos27-Jul-04 15:33 
GeneralRe: Missing Source Code PinstaffSmitha Vijayan29-Jul-04 18:43 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140709.1 | Last Updated 30 Dec 2004
Article Copyright 2004 by Kastellanos Nikos
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid