在开发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="http://www.aspcool.com/lanmu/real-url-of-en">EN</a>
</li>
<li class="fr">
<a href="http://www.aspcool.com/lanmu/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="http://www.aspcool.com/lanmu/{@url}">
<xsl:value-of select="@title"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
这样就好了,以后想改HTML就直接改上面的XSL文件就可以了,再也不用重新编译了。而且这样做就把表现层的东西从代码中分离了,比较符合现代的软件设计思想。
可以看到上面这个控件是在SharePoint中用的,但是其思想完全不局限于SharePoint。

BK网络学院主要内容:平面设计教程,网站开发在线教程,网页制作教程,服务器教程,网络编程,数据库教程等。