XSLT Transformation in ASP.net MVC framework

In my last post I talked about using a partial view to render hierarchical data, however XSL transformation looks more appropriate for such cases. ASP.Net has XML control which can display XML document using XSL Transformations. I will show you how similar thing can be achieved in ASP.NET MVC Framework.

The Model

I have a very simple Tab class which can have a collection of sub-tab. this class can be used to create infinite level of tab hierarchy. I have added XmlAttributes to my properties so that when class is serialized those properties are sterilized as attributes.

public class  Tab {

    [XmlAttribute(
"id" )]
    
public int  ID {  get; set;  }
    
    [XmlAttribute(
"name" )]
    
public string  Name {  get; set;  }

    [XmlAttribute(
"alias" )]
    
public string  Alias {  get; set;  }

    
public  List<Tab> Tabs {  get; set;  }
}
 

The Controller

I have a single controller called TabController it has TabXSLT action, it does two things 1) Gets list of tabs from by calling service and then serializes it to XML and 2) Passes that XML to view.

public class  TabController : Controller {
    [ControllerAction]
    
public void  TabXSLT() {
        List<Tab> tabs 
TabService.GetTabs() ;
        
XmlSerializer serilizer 
            new 
XmlSerializer( typeof (List<Tab>)) ;

        
MemoryStream stream  = new  MemoryStream() ;
        
stream.Seek( 0 , SeekOrigin.Begin) ;
        
        
serilizer.Serialize(stream, tabs) ;
        
XmlDocument doc  = new  XmlDocument() ;
        
stream.Seek( 0 , SeekOrigin.Begin) ;
        
doc.Load(stream) ;
        
ViewData[ "tabs" doc ;
        
RenderView( "TabXSLT" ) ;
    
}
    
}
 

View extension for XSLT

MVC Framework does not have concept of the control, Instead UI Helpers and ViewExtensions will enable you to wrap common functionality. I have used view extension in my case to inject additional method in view which will allow me render transformed XML inside my view.

public static class  XSLTViewExtensions {
    
    
public static void  RenderXML( this  ViewPage page
        , XmlDocument xmlDocument
        , 
string  XSLTPath,
        Dictionary<
string , string > xslArgParams) 
    {
        ViewContext context 
page.Html.ViewContext ;
        
XsltArgumentList xslArgs  = new  XsltArgumentList() ;
        if 
(xslArgParams ! = null ) {
            
foreach  ( string  key  in  xslArgParams.Keys) {
                xslArgs.AddParam(key, 
null ,xslArgParams[key]) ;
            
}
        }
        XslCompiledTransform t 
= new  XslCompiledTransform() ;
        
t.Load(XSLTPath) ;
        
t.Transform(xmlDocument, xslArgs, 
            context.HttpContext.Response.Output)
;
    
}

}
 

The View

I have the TabXSLT.aspx view in /Views/Tab folder. Inside my view I am calling extension method by passing XML data that I got from controller and path to XSLT file.

< %@  Page Language ="C#"  
         Inherits
="System.Web.Mvc.ViewPage"  
         MasterPageFile
="~/Views/Shared/Site.Master"  % >

< %@  Import Namespace ="ExperimentsWithMVC.Models"  % >
< %@  Import Namespace ="System.Collections.Generic"  % >
< %@  Import Namespace ="System.Web.Mvc"  % >
< %@  Import Namespace ="System.Xml"  % >
< asp:Content  ID ="Content2"  
             ContentPlaceHolderID
="MainContentPlaceHolder"  
             runat
="server">
    
< h2 > Tabs with XSLT </ h2 >
    
< %  this.RenderXML((XmlDocument)ViewData[ "tabs"]
           , Server.MapPath(
"~/content/tabs.xsl"),null);%>

</ asp:Content >
 

The XSLT

< ?xml  version ="1.0"  encoding ="utf-8"?>
< xsl:stylesheet  version ="1.0"  
                xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"   >
  
< xsl:output  omit-xml-declaration ="yes"   />
  
  <
xsl:template  match ="/">
    
< xsl:apply-templates > </ xsl:apply-templates >
  
</ xsl:template >

  
< xsl:template  match ="Tab">
    
< li >
      
< xsl:value-of  select ="@name"/>
      <
xsl:apply-templates  select ="Tabs"> </ xsl:apply-templates >
    
</ li >
  
</ xsl:template >

  
< xsl:template  match ="Tabs">
    
< ul >
      
< xsl:apply-templates  select ="Tab"   />
    </
ul >
  
</ xsl:template >

  
< xsl:template  match ="ArrayOfTab">
    
< ul >
      
< xsl:apply-templates  select ="Tab"   />
    </
ul >
  
</ xsl:template >
</ xsl:stylesheet >
 

The result

Result is nested unordered list as shown below, each item can have sub item up to nth level.

Parting Thoughts

I have used extension method to inject additional method in my current ViewPage class but it might be more appropriate to group similar UI helper methods in static class, for example you can have AJAXHelper, HTMLHelper, XMLHelper etc.

Published Friday, February 08, 2008 8:11 PM by jigar
Filed under: , ,

Comments

# ASP.NET MVC Archived Buzz, Page 1

Thursday, September 11, 2008 12:56 AM by ASP.NET MVC Archived Buzz, Page 1

Pingback from  ASP.NET MVC Archived Buzz, Page 1

# re: XSLT Transformation in ASP.net MVC framework

Thursday, April 02, 2009 5:37 AM by bhupendran

Hi. ur post is little helpful for me but can u give me a full flegde example. My requirement is to generate dynamic server controls using xml and xslt in mvc framework

# re: XSLT Transformation in ASP.net MVC framework

Thursday, May 07, 2009 3:23 AM by Richie Ryan R Reyes

The attached file doesn't work... (VS2k8)

# re: XSLT Transformation in ASP.net MVC framework

Wednesday, June 10, 2009 8:35 PM by bleevo

Check this out if you want to use XSLT and ASP.MVC

www.bleevo.com/.../aspnet-mvc-xslt-iviewengine

# re: XSLT Transformation in ASP.net MVC framework

Friday, September 18, 2009 3:23 PM by Florian

Works like a charm. Just what I needed to get started.

Leave a Comment

(required) 
(required) 
(optional)
(required)