Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using XSLT in ASP .NET MVC 3

Does anybody has experience in in using XSLT in asp.net MVC 3?

The intention here is to be able to develop pages whose styling and layout can be changed at runtime based on some conditions. for example, user profile.

One solution is that We can use separate layout pages and set that at runtime by setting the dynamic property Viewbag. But this approach would require a recompile if we want to add new layout to the page. I was thinking that may be we could load an XSL dynamically in the controller at runtime and bind it to the model object at runtime. The HTML content can then be rendered in a predefined section in the page.

A code snippet would be a great help.

like image 809
Akhilesh Avatar asked Sep 19 '11 13:09

Akhilesh


1 Answers

I just built a site that transforms XML into HTML for display in MVC3. I used the second technique, where the controller determines the XML and XSLT files to use, and passes them in the model. An HTML helper in the view actually performs the transform.

In this case I'm rendering a conference program, so that's what Program refers to below. Parameters can be supplied to the stylesheet; below, I'm supplying a base URL as a parameter that will be turned into links in the generated HTML.

The model:

public class ProgramModel
{
    public string ProgramFilename { get; set; }
    public string StylesheetFilename { get; set; }

    public Dictionary<string, string> Parameters { get; protected set; }

    public ProgramModel()
    {
        Parameters = new Dictionary<string, string>();
    }
}

The controller:

    [OutputCache(Duration=1000)]
    public ActionResult Index()
    {
        string xmlFile = Server.MapPath("~/Program.xml");
        string xsltFile = Server.MapPath("~/Program-index.xslt");
        Response.AddCacheDependency(new CacheDependency(xmlFile), new CacheDependency(xsltFile));

        ProgramModel model = new ProgramModel();
        model.ProgramFilename = xmlFile;
        model.StylesheetFilename = xsltFile;
        model.Parameters["baseDayUrl"] = Url.Action("Day");

        return View(model);
    }

The helper:

public static class HtmlHelperXmlExtensions
{
    /// <summary>
    /// Applies an XSL transformation to an XML document.
    /// </summary>
    public static HtmlString RenderXml(this HtmlHelper helper, string xmlPath, string xsltPath, IDictionary<string,string> parameters)
    {
        XsltArgumentList args = new XsltArgumentList();
        if (parameters != null)
            foreach (string key in parameters.Keys)
                args.AddParam(key, "", parameters[key]);

        XslCompiledTransform t = new XslCompiledTransform();
        t.Load(xsltPath);

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Parse;
        settings.ValidationType = ValidationType.DTD;

        using (XmlReader reader = XmlReader.Create(xmlPath, settings))
        {
            StringWriter writer = new StringWriter();
            t.Transform(reader, args, writer);
            return new HtmlString(writer.ToString());
        }

    }

}

The view:

<div data-role="content">
@Html.RenderXml(Model.ProgramFilename, Model.StylesheetFilename, Model.Parameters)
</div>
like image 151
Carl Raymond Avatar answered Nov 18 '22 15:11

Carl Raymond