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>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…