在開發(fā)Web Control的時候,經(jīng)常需要在源代碼中嵌入一些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的表現(xiàn),比如把CSS Class從“l(fā)ng” 改為“l(fā)anguage”,那么我們就必須要在這個代碼里面修改,并且需要重新編譯,這樣就帶來了極大的不方便。我們需要一種能夠不需要重新編譯代碼就可以改變HTML的方法。 這篇文章就介紹一種這樣的方法,解決方案是XML + XSL
原理是,在上面方法中,我們不直接負責HTML輸出,而是我們構(gòu)建一個XML文件在內(nèi)存中,然后我們需要自己編寫一個XSL文件來定義這個XML的表現(xiàn)!
具體這樣:(一共兩步) 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=" <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文件就可以了,再也不用重新編譯了。而且這樣做就把表現(xiàn)層的東西從代碼中分離了,比較符合現(xiàn)代的軟件設計思想。 可以看到上面這個控件是在SharePoint中用的,但是其思想完全不局限于SharePoint
|