我們已經知道,XML文件用來存放數據,而如何表現XML則要借助其他的手段。我們現在推薦您使用IE5.0。如果您在IE5.0中直接打開 一個XML文件,那麼你看到的只是XML的源代碼;要進一步以更靈活更豐富的形式來表示,就要借助於CSS或XSL。如何使用CSS,建議閱讀CSS2規范(W3C建議) . 這裡我們想介紹如何用XSL來表現您的XML.
首先我們給出一個XML文件(stock-sorter.XML)的簡單例子:
<?XML:stylesheet type="text/xsl" href="simple.xsl"?>
<portfolio xmlns="x-schema:portfolio-schema.XML">
<description>Technology Stock Index</description>
<date>1999-08-13T15:56:00</date>
<stock>
<symbol>AOL</symbol>
<name>america online inc</name>
<price>92.250</price>
<change>-1.125</change>
<percent>-1.20</percent>
<volume>4.99</volume>
</stock>
<stock>
<symbol>CSCO</symbol>
<name>cisco sys inc</name>
<price>50.688</price>
<change>-1.688</change>
<percent>-3.22</percent>
<volume>18.23</volume>
</stock>
<stock>
<symbol>DELL</symbol>
<name>dell computer corp</name>
<price>53.000</price>
<change>-3.063</change>
<percent>-5.46</percent>
<volume>32.95</volume>
</stock>
......
</portfolio>
其中元素portfolio是在portfolio文件中定義的:
<?XML version="1.0" ?>
<Schema xmlns="urn:schemas-microsoft-com:xml-data" XMLns:dt="urn:schemas-microsoft-com:datatypes">
<ElementType name="date" dt:type="dateTime"/>
<ElementType name="description"/>
><ElementType name="symbol"/>
<ElementType name="name"/>
<ElementType name="price" dt:type="fixed.14.4"/>
<ElementType name="change" dt:type="fixed.14.4"/>
<ElementType name="percent" dt:type="fixed.14.4"/>
<ElementType name="volume" dt:type="fixed.14.4"/>
<ElementType name="portfolio" content="eltOnly">
<group minOccurs="0" maxOccurs="1">
<element type="description" />
</group>
<group minOccurs="0" maxOccurs="1">
<element type="date" />
</group>
<group minOccurs="1" maxOccurs="1">
<element type="stock" />
</group>
</ElementType>
<ElementType name="stock" content="eltOnly">
<element type="symbol" />
<element type="name" />
<element type="price" />
<element type="change" />
<element type="percent" />
<element type="volume" />
</ElementType>
</Schema>
在stock-sorter.xml文件中第一行的處理指令(Process Instruction): <?xml:stylesheet type="text/xsl" href="simple.xsl"?> 表示由simple.xsl來規定XML的表現方式。當我們在IE中打開該XML時,浏覽器根據其中所規定的XSL的位置去得到該XSL,並通過XSL 處理器將XML和XSL結合成為XSL定義的輸出形式。這裡我們將其輸出形式定為Html格式,是為了方便在浏覽器中直接顯示。好,讓我們來看簡單的XSL文件是怎樣寫的:
Simple.xsl:
<?XML version="1.0">
<Html XMLns:xsl="http://www.w3.org/TR/WD-xsl">
<BODY >
<xsl:for-each select="portfolio/stock">
<DIV >
<SPAN >
<xsl:value-of select="name"/></SPAN>
- <xsl:value-of select="price"/>
</DIV>
<DIV >
<xsl:value-of select="description"/>
<SPAN >
(change:<xsl:value-of select="change"/> )
</SPAN>
</DIV>
</xsl:for-each>
</BODY>
</Html>
以上的代碼很容易理解,關鍵是采用選擇語句(for-each select)在XML樹結構中進行選擇,並把得到的結果樹(Result Tree)包容於Html中(value-of select).其實這只是簡單的XSL語句.XSL的腳本語言叫做ECMAScript,它是在JavaScript的基礎上發展的。如果我們要改變stock-sorter.XML的表現,只要在stlye sheet的href中指定另外的XSL文件。
在XSL的規范定義了XML的匹配模板(Template),設置匹配字符,則處理時將從XML的根節點(Root Node)搜索匹配的節點.如:<xsl: template match="/">.通常構成Html格式的模板,它可以只是XSL的一部分。您還可以寫XSL的腳本,舉個示例:
<xsl:script><![CDATA[
function Demo(node)
{
total = 0;
volumes = node.selectNodes("/portfolio/stock/volume");
for (v = volumes.nextNode(); v; v = volumes.nextNode())
total += v.nodeTypedValue;
return formatNumber(total, "#") + " million shares";
}
]]></xsl:script>
還可以加XSL的注釋,如:
<xsl:comment><![CDATA[
function sort(fIEld)
{
sortField.value = fIEld;
listing.innerHtml = source.documentElement.transformNode(stylesheet);
}
]]></xsl:comment>
讓我們給出另一個較為復雜的例子,並據此進一步學習XSL:
Complex.xsl:
<?XML version="1.0"?>
<xsl:stylesheet XMLns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<Html>
<HEAD>
<STYLE>
BODY {margin:0}
.bg {font:8pt Verdana; background-color:purple; color:white}
H1 {font:bold 14pt Verdana; width:100%; margin-top:1em}
.row {font:8pt Verdana; border-bottom:1px solid #CC88CC}
.header {font:bold 9pt Verdana; cursor:hand; padding:2px; border:2px outset gray}
.up {background-color:#DDFFDD;}
.down {background-color:#FFDDDD;}
</STYLE>
</HEAD>
<SCRIPT>
<xsl:comment><![CDATA[
function sort(fIEld)
{
sortField.value = fIEld;
listing.innerHtml = source.documentElement.transformNode(stylesheet);
}
]]></xsl:comment>
</SCRIPT>
<SCRIPT for="window" event="onload">
<xsl:comment><![CDATA[
stylesheet = document.XSLDocument;
source = document.XMLDocument;
sortFIEld = document.XSLDocument.selectSingleNode("//@order-by");
]]></xsl:comment>
</SCRIPT>
<BODY>
<TABLE width="100%" cellspacing="0">
<TR>
<TD class="bg"/>
<TD class="bg">
<H1> <xsl:value-of select="portfolio/description"/> for <xsl:apply-templates select="portfolio/date"/></H1>
<DIV>Average change: <B><xsl:eval>averageChange(this)</xsl:eval></B></DIV>
<DIV>Total volume: <B><xsl:eval>totalVolume(this)</xsl:eval></B></DIV>
</TD>
</TR>
<TR>
<TD class="bg" width="120" valign="top">
<P>Click on the column headers to sort by that fIEld.</P>
<P>Demonstration of custom formatting of data typed values and local reapplication of the stylesheet.</P>
<P>Stocks losing more than 5% indicated in red. Stocks gaining value indicated in green.</P>
</TD>
<TD class="bg" valign="top">
<DIV id="listing"><xsl:apply-templates match="portfolio"/></DIV>
</TD>
</TR>
</TABLE>
</BODY>
</Html>
</xsl:template>
<xsl:template match="portfolio">
<TABLE >
<THEAD>
<TD width="200"><DIV class="header" onClick="sort(''name'')">Company</DIV></TD>
<TD width="80"><DIV class="header" onClick="sort(''symbol'')">Symbol</DIV></TD>
<TD width="80"><DIV class="header" onClick="sort(''price'')">Price</DIV></TD>
<TD width="80"><DIV class="header" onClick="sort(''change'')">Change</DIV></TD>
<TD width="80"><DIV class="header" onClick="sort(''percent'')">%Change</DIV></TD>
<TD width="80"><DIV class="header" onClick="sort(''volume'')">Volume</DIV></TD>
</THEAD>
<xsl:for-each select="stock" order-by="symbol">
<TR>
<xsl:for-each select="change">
<xsl:if expr="this.nodeTypedValue > 0">
<xsl:attribute name="class">up</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="percent">
<xsl:if expr="this.nodeTypedValue < -5">
<xsl:attribute name="class">down</xsl:attribute>
</xsl:if>
</xsl:for-each>
<TD><DIV class="row"><xsl:value-of select="name"/></DIV></TD>
<TD><DIV class="row"><xsl:value-of select="symbol"/></DIV></TD>
<TD><DIV class="row" ><xsl:apply-templates select="price"/></DIV></TD>
<TD><DIV class="row" ><xsl:apply-templates select="change"/></DIV></TD>
<TD><DIV class="row" ><xsl:apply-templates select="percent"/></DIV></TD>
<TD><DIV class="row" ><xsl:apply-templates select="volume"/></DIV></TD>
</TR>
</xsl:for-each>
</TABLE>
</xsl:template>
<xsl:template match="date">
<xsl:eval>formatDate(this.nodeTypedValue, "MMMM dd'','' yyyy")</xsl:eval> at <xsl:eval>formatTime(this.nodeTypedValue, "hh:mm tt")</xsl:eval>
</xsl:template>
<xsl:template match="price | change">
<xsl:eval>formatNumber(this.nodeTypedValue, "$0.00")</xsl:eval>
</xsl:template>
<xsl:template match="percent">
<xsl:if expr="this.nodeTypedValue > 0">+</xsl:if>
<xsl:eval>formatNumber(this.nodeTypedValue, "0.0")</xsl:eval>%
</xsl:template>
<xsl:template match="volume">
<xsl:eval>formatNumber(this.nodeTypedValue * 1000000, "#,###,###")</xsl:eval>
</xsl:template>
<xsl:script><![CDATA[
function totalVolume(node)
{
total = 0;
volumes = node.selectNodes("/portfolio/stock/volu
me");
for (v = volumes.nextNode(); v; v = volumes.nextNode())
total += v.nodeTypedValue;
return formatNumber(total, "#") + " million shares";
}
function averageChange(node)
{
total = 0;
percents = node.selectNodes("/portfolio/stock/percent");
count = percents.length;
for (p = percents.nextNode(); p; p = percents.nextNode())
total += p.nodeTypedValue;
return formatNumber(total/count, "#.0") + "%";
}
]]></xsl:script>
</xsl:stylesheet>
如果你要顯示中文,你只要在XML和XSL文件的的開頭分別加上:<?XML version="1.0" encoding="gb2312"?>即可.試試看!