表A:1-0-1,this is a test
3-1-1,this is a test
4-3-1,this is a test
5-3-1,this is a test
2-0-2,this is a test
上面是BBS主題列表的一個例子。一般來說,假如不是使用Oracle(Oracle 有一條查詢語句可以自動生成家族樹,請查閱Select ... startwith ... connect by ...語句),那麼如何實現上例的列表是一件費事的工作(相信許多程序員都寫過)。
如果我們改用XML來實現,那麼結果會怎麼樣呢?
現在我們使用"Select * from bbs"從數據庫中查詢貼子,並以XML格式返回(如果你是用ADO,那麼可以用其RecordSet.Save ... adPersistXML直接生成,當然如果你不喜歡ADO生成的格式,可用程序生成,如本例):
表B:
<?XML version="1.0"?>
<?XML-stylesheet type="text/xsl" href="b.xsl"?>
<bbs>
<post sid="4" pid="3" aid="1">
<title>4-3-1,this is a test</title>
<content>slddfJSlajfsdljf</content>
</post>
<post sid="5" pid="3" aid="1">
<title>5-3-1,this is a test</title>
<content>slddfJSlajfsdljf</content>
</post>
<post sid="3" pid="1" aid="1">
<title>3-1-1,this is a test</title>
<content>slddfJSlajfsdljf</content>
</post>
<post sid="1" pid="0" aid="1">
<title>1-0-1,this is a test</title>
<content>slddfJSlajfsdljf</content>
</post>
<post sid="2" pid="0" aid="2">
<title>2-0-2,this is a test</title>
<content>slddfJSlajfsdljf</content>
</post>
</bbs>
說明:這裡sid是貼子的id號,pid是貼子的父id號。title是標題,content是貼子的內容。
上表中第二行是指定使用b.XSL來轉換XML內容。這是提供給IE5的信息。假如你使用XMLDOM,那麼可以不要這條信息。
我們再來看看將上表的XML內容顯示成表A形式的XSL文件是怎麼實現的:
表C:b.XSL
<?XML version=''1.0''?>
<xsl:stylesheet XMLns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<Html>
<body>
<xsl:apply-templates select="*"/>
</body>
</Html>
</xsl:template>
<xsl:template match="post">
<li>
<div>
<xsl:attribute name="title"><xsl:value-of select="content"/></xsl:attribute>
<xsl:value-of select="title"/>
<xsl:if test="/bbs/post[@pid=context()/@sid]">
<xsl:element name="ul">
<xsl:apply-templates select="/bbs/post[@pid=context()/@sid]"/>
</xsl:element>
</xsl:if>
</div>
</li>
</xsl:template>
<xsl:template match="bbs">
<ul>
<xsl:apply-templates select="post[@pid=0]"/>
</ul>
</xsl:template>
</xsl:stylesheet>
現在,你將表B的內容存為abc.XML,將表C的內容存為b.xsl,然後在IE5中打開,你就可以看到和表A一樣的內容了。
因此可以看出,XSL文件解定了最終的顯示結果。假如你有多個子論壇,那麼無需更改論壇程序,只要為各個子論壇提供不同XSL文件,就可以讓各個子論壇的版而不論風格畫面還是主題排列都會具有獨特的表現。如果提供
免費論壇服務,那麼允許論壇申請者定制自已的XSL文件將是一個良好的選擇。
但是假如客戶端不支持XML,該怎麼辦呢?答案很簡單,由服務端先將XML轉換成Html,再傳到客戶端。
下面我們以IIS4/5+IE5+ASP來實現這個例子(服務器必需安裝IE5):
<%@ LANGUAGE = JScript %>
<%
Set rsXML=Server.CreateObject("ADODB.RecordSet");
sSQL = “SELECT * from bbs"
sConn = “你自個兒寫”
rsXML.CursorLocation = adUseClIEnt
rsXML.Open sSQL, sConn, adOpenStatic
//指定XSL文件位置
var styleFile = Server.MapPath("simple.xsl");
// Save the XML to XMLDOM
var source = Server.CreateObject("Microsoft.XMLDOM");
''rsXML.Save source, adPersistXML
''我相當不喜歡ADO直接Save出來的XML文檔,我總是這樣做:
Dim GetData,v
GetData = GetData & "<bbs>"
while not RS_ForumInfo.EOF
GetData = GetData & "<post>"
for i = 0 to RS_ForumInfo.FIElds.Count -1
set v = RS_ForumInfo.FIElds.Item(i)
if (v.Type=201)or(v.Type=203)or(v.Type=205) then
GetData = GetData& "<" & RS_ForumInfo.FIElds.Item(i).Name &">" &_
"<![CDATA[" & RS_ForumInfo.FIElds.Item(i).Value & "]]>" &_
"</" & RS_ForumInfo.FIElds.Item(i).Name &">"
else
GetData = GetData& "<" & RS_ForumInfo.FIElds.Item(i).Name &">" &_
RS_ForumInfo.FIElds.Item(i).Value &_
"</" & RS_ForumInfo.FIElds.Item(i).Name &">"
end if
set v = Nothing
next
GetData = GetData & "</post>"
RS_ForumInfo.MoveNext
wend
GetData = GetData & "</bbs>"
source.loadXML GetData
// Load the XSL
var style = Server.CreateObject("Microsoft.XMLDOM");
style.async = false;
style.load(styleFile);
Response.Write(source.transformNode(style));
%>
當然,由於此處為了簡便,直接使用ADO來生成XML,因此simple.xsl和上面的b.xsl是不同的。
讀者可以參考上例和XSL參考資料(2000年的MSDN有比較詳細的XML/XSL SDK文檔)來編寫。(完)