Article

Build an XML/XSLT driven Website with .NET

Page: 1 2 3 Next

The Web Application Base

By default, the application base is extracted from Web.Config, which is the configuration file for the Web application. This is an XML file that contains the configuration of the Web application. The file contains numerous system settings for the site. There is a section for custom application settings called <appSettings>. The configuration is accessible through ConfigurationSettings class, part of the System.Configuration namespace. The code is as simple as:

<configuration>  
...  
  <appSettings>  
     <add key="ui.base" value="ui\" />  
  </appSettings>  
</configuration>  
 
m_applicationBase = ConfigurationSettings.AppSettings["ui.base"];

The UI Engine determines the full path to the XSLT file using the application base, skin, locale and XSLT file name:

string path = m_applicationBase;  
 
// check for skin  
if(m_skin.Length > 0)  
{  
   path += m_skin + "\\";  
}  
 
// check for globalization  
if(m_locale > 0)  
{  
   path += m_locale.ToString() + "\\";  
}  
 
// add visualization parameters  
arg.AddParam("ui.path","",path);  
arg.AddParam("ui.skin","",m_skin);  
arg.AddParam("ui.locale","", m_locale.ToString());  
 
// add the stylesheet  
path += stylesheet;

To switch skins, we set the name of the skin in the query string:

http://localhost/bookstore/title.aspx?skin=dark

Since HTTP is stateless protocol, the skin name needs to be persisted across different calls. There are a couple of different methods: session variables, query parameters, cookies, and database persistence.

Session variables would be the preferred method if your site was designed to use sessions. Keeping the variables on the server reduces the complexity of the pages and the amount of data transferred back and forth. However, such sites don't scale as well as sites that don't use sessions, due to session management overhead.

The query parameters and cookies methods don't require server sessions, and they scale better, but they also complicate the site design, and will be affected if the user turns off the browser support for cookies. Another issue is security: sensitive data such as credit card numbers shouldn't be sent as part of query parameters or cookies, as the data won't be encrypted if secure connections are not used.

Since the sample site doesn't require sessions and there are few parameters, I choose to pass the state though the URL query's parameters, that is, skin=dark is augmented automatically to each URL. This is done in the XSL files.

<a href="title.aspx?skin={$ui.skin}&amp;lcid={$ui.locale}">...

A configuration page could be built that showed the available skins or locales. For example:

http://localhost/bookstore/title.aspx?skin=dark&lcid=1026

This URL will display the book list by title using skin "dark" and localized in Bulgarian -- 1026. Note that only the UI is localized; the data itself is not. By default, the encoding of the HTML is UTF-8, which works with languages. However some browsers don't support UTF-8, and locale-specific encoding might be added to the XSL stylesheets.

The visualization parameters are added as parameters to the XSLT transformation. They're visible in the XSLT and can be used to find HTML elements as CSS and images. For example, we'd use the ui.path parameter to find the CSS file and the image:

<LINK REL="stylesheet" TYPE="text/css" HREF="{$ui.path}css/default.css" />  
<img src="{$ui.path}view.gif" alt="view book details" border="0" />

Additional custom parameters for each XSLT file can be added via XsltArgumentList arg, part of the Transform method.

Once the relative path is determined, it is converted to the absolute path and loaded into XslTransform object:

XslTransform xslt = new XslTransform();  
xslt.Load(ctx.Server.MapPath(path));

The XML Data is passed as string and loaded into and XPathDocument:

XPathDocument mydata = new XPathDocument(new  
XmlTextReader(xmldoc,XmlNodeType.Document,null));

The transformation is performed and the result is written to a string:

StringWriter sw = new StringWriter();  
xslt.Transform(mydata,arg,sw);

The string is written to the Response object with buffering turned on:

ctx.Response.BufferOutput = true;  
ctx.Response.Write(sw.ToString());  
ctx.Response.End();

If you liked this article, share the love:
Print-Friendly Version Suggest an Article