用XSL来定义ASP.NET Web Control

2008-02-29 10:14:18.0     推荐:0    收藏:0    评论:0     来源:www.ASPCool.com
在开发Web Control的时候,经常需要在源代码中嵌入一些HTML代码, 比如这样(代码片段):

protected override void RenderContents(HtmlTextWriter output)
{
SPList myList = GetListByName(List);
if (myList != null)
{
uint currentLanguageCode = getCurrentLanguageCode();
output.WriteBeginTag("ul");
output.WriteAttribute("class", "lng");
output.WriteLine(HtmlTextWriter.TagRightChar);

foreach (SPListItem item in myList.Items)
{
if (uint.Parse((string)item["Language Code"]) != getCurrentLanguageCode())
{
output.WriteBeginTag("li");
output.WriteAttribute("class", (string)item["CSS Class"]);
output.WriteLine(HtmlTextWriter.TagRightChar);
output.WriteBeginTag("a");
output.WriteAttribute("href", ((Microsoft.SharePoint.Publishing.Fields.LinkFieldValue)item["Language URL"]).NavigateUrl);
output.WriteLine(HtmlTextWriter.TagRightChar);
output.Write((string)item["Title"]);
output.WriteEndTag("a");
output.WriteEndTag("li");
}
}
output.WriteEndTag("ul");
}
}



这个控件的HTML会输出成类似这样:


<ul class="lng">
<li class="en">
<a href="real-url-of-en">EN</a>
</li>
<li class="fr">
<a href="real-url-of-fr">FR</a>
</li>
</ul>

但是这样做有个问题,假如我们想改变这个web control的表现,比如把CSS Class从“lng” 改为“language”,那么我们就必须要在这个代码里面修改,并且需要重新编译,这样就带来了极大的不方便。我们需要一种能够不需要重新编译代码就可以改变HTML的方法。
这篇文章就介绍一种这样的方法,解决方案是XML + XSL

原理是,在上面方法中,我们不直接负责HTML输出,而是我们构建一个XML文件在内存中,然后我们需要自己编写一个XSL文件来定义这个XML的表现。 

具体这样:(一共两步)
1。 改写上面方法为:


protected override void RenderContents(HtmlTextWriter output)
{

SPList myList = GetListByName(List);

if (myList != null)
{
try
{
XslCompiledTransform transformer = new XslCompiledTransform();
string s = SPUtility.GetGenericSetupPath("TEMPLATE\\LAYOUTS") + XslFileRelativeUrl;
transformer.Load(s);
StringWriter result = new StringWriter();
XmlDocument mydoc = BuildXML(myList);
transformer.Transform(mydoc, null, result);
output.WriteLine(result.ToString());
}
catch (Exception ex)
{
Page.Response.Write(ex.Message);
}
}
}


其中的BuildXML()方法为:


// <languages>
// <language title="EN" code="1033" cssclass="en" url="en-url" />
// <language title="FR" code="1036" cssclass="fr" url="fr-url" />
// </languages>
public XmlDocument BuildXML(SPList myList)
{
if (myList != null)
{
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode languagesNode = doc.CreateElement("languages");
doc.AppendChild(languagesNode);

foreach (SPListItem item in myList.Items)
{
if (uint.Parse((string)item["Language Code"]) != getCurrentLanguageCode())
{
XmlNode languageNode = doc.CreateElement("language");

XmlAttribute languageAttribute = doc.CreateAttribute("title");
languageAttribute.Value = (string)item["Title"];
languageNode.Attributes.Append(languageAttribute);

languageAttribute = doc.CreateAttribute("code");
languageAttribute.Value = (string)item["Language Code"];
languageNode.Attributes.Append(languageAttribute);

languageAttribute = doc.CreateAttribute("cssclass");
languageAttribute.Value = (string)item["CSS Class"];
languageNode.Attributes.Append(languageAttribute);

languageAttribute = doc.CreateAttribute("url");
languageAttribute.Value = ((Microsoft.SharePoint.Publishing.Fields.LinkFieldValue)item["Language URL"]).NavigateUrl;
languageNode.Attributes.Append(languageAttribute);

languagesNode.AppendChild(languageNode);

}
}
return doc;
}
else return null;
}


2. 定义XSL文件:


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<ul class="lng">
<xsl:for-each select="languages/language">
<li class="{@cssclass}">
<a href="{@url}">
<xsl:value-of select="@title"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>

这样就好了,以后想改HTML就直接改上面的XSL文件就可以了,再也不用重新编译了。而且这样做就把表现层的东西从代码中分离了,比较符合现代的软件设计思想。
可以看到上面这个控件是在SharePoint中用的,但是其思想完全不局限于SharePoint。

您可以针对本文进行:[评论]  [收藏]  [推荐]  
  • 共有0条评论  点击查看更多评论
  • 网友评论仅供网友表达个人看法,并不表明e800同意其观点或证实其描述
我想发表评论:
用户名密码
  • 匿名发表
    验证码: