DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 用XSL把XML的數據轉換成完美的多列表格形式
用XSL把XML的數據轉換成完美的多列表格形式
編輯:XML詳解     

摘要:本文通過實際的例子來說明如何在XSL中實現對XML數據轉換成完美的多列表格。

在利用XSL對XML進行轉換時,有時候需要把XML轉換成多列的Table元素,這個問題經常會困擾許多人,如果不生成Table的話,只需要對循環中的節點進行位置取模後判斷,然後用<br/>換行即可。但有時候為了用戶需要和界面的美觀,需要生成多行多列的Table,常用的方法是采用following-sibling進行判斷,比如下面的代碼:

<?XML version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet version="1.0" XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
            XMLns:copyRight="http://xml.sz.luohuedu.net/">
            <xsl:template match="/">
            <table bgcolor="snow" border="1" cellpadding="5" cellspacing="2" borderColor="darkorange"
                style="font-size:9pt">
                <xsl:for-each select="/Items/Item[position() mod 3 = 1]">
                <tr>
                    <td width="33%" align="center" valign="middle">
                    <xsl:apply-templates select="."/>
                    </td>
                    <td width="34%" align="center" valign="middle">
                    <xsl:apply-templates select="following-sibling::Item[position() = 1]"/>
                    </td>
                    <td width="33%" align="center" valign="middle">
                    <xsl:apply-templates select="following-sibling::Item[position() = 2]"/>
                    </td>
                </tr>
                </xsl:for-each>
            </table>
            </xsl:template>
            <xsl:template match="/Items/Item">
            <a target="_blank">
            <xsl:attribute name="href">
            <xsl:if test="contains(Url,'@')">mailto:</xsl:if><xsl:value-of select="Url"/></xsl:attribute>
            <xsl:value-of select="Title"/>
            </a>
            </xsl:template>
            </xsl:stylesheet>           
轉換結果如下圖所示:

但是,從上面的結果圖可以看出,如果數據記錄不是表格列數的整數倍的時候,最後一行的最後幾列不會生成出來,即在Html裡缺少<td></td>標記。

要解決上面的不足,我們必須先計算要轉換的記錄的總數,然後計算出相差的記錄數,再進行補齊。下面就對這一過程的解釋。

在進行這個功能之前,首先了解一個如何在XSL中實現類似for(i=0;i<n;i++)的循環,下面就是實現這一個功能的例子:

<?XML version="1.0" encoding="GB2312"?>
            <xsl:stylesheet version="1.0" XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
            XMLns:copyRight="http://xml.sz.luohuedu.net/">
            <!-- 下面的三個變量可以由XML中取得,做為例子,這裡直接定義了初始值 -->
            <!-- 定義初始值 -->
            <xsl:variable name="varStart" select="0"/>
            <!-- 定義結束值 -->
            <xsl:variable name="varEnd" select="35"/>
            <!-- 定義循環步長 -->
            <xsl:variable name="varStep" select="2"/>
            <xsl:template match="/">
            <xsl:call-template name="MyLoopFun">
            <xsl:with-param name="varStart" select="$varStart">
            </xsl:with-param>
            </xsl:call-template>
            </xsl:template>
            <xsl:template name="MyLoopFun">
            <xsl:param name="varStart"/>
            <xsl:if test="$varStart &lt; $varEnd">
            <!-- 輸出格式定義 -->
            <a target="_blank" href="http://xml.sz.luohuedu.net/?{$varStart}">
            <xsl:attribute name="title"><xsl:value-of select="$varStart"/></xsl:attribute>
            <xsl:value-of select="$varStart"/>
            </a>
            <xsl:if test="$varStart &lt; ($varEnd - $varStep)"> , </xsl:if>
            <xsl:call-template name="MyLoopFun">
            <xsl:with-param name="varStart">
            <xsl:value-of select="$varStart + $varStep"/>
            </xsl:with-param>
            </xsl:call-template>
            </xsl:if>
            </xsl:template>
            </xsl:stylesheet>           
理解了上面的原理之後,下面就是我們最後的代碼,程序已經做了注釋:

<?XML version="1.0" encoding="UTF-8"?>
            <xsl:stylesheet version="1.0" XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
            XMLns:copyRight="http://xml.sz.luohuedu.net/">
            <xsl:template match="/">
            <!-- 定義常量 -->
            <xsl:variable name="strTrLeft" select="'&lt;tr&gt;'"/>
            <xsl:variable name="strTrRight" select="'&lt;/tr&gt;'"/>
            <!-- 計算總記錄數 -->
            <xsl:variable name="nTotal" select="count(/Items/Item)"/>
            <!-- 定義列數 -->
            <xsl:variable name="nCols" select="3"/>
            <!-- 計算需要的補齊的列數 -->
            <xsl:variable name="nLefted" select="$nCols - ($nTotal mod $nCols)"/>
            <!-- 計算不需要補齊的行數 -->
            <xsl:variable name="nNotProcessedRow" select="$nTotal -  ($nTotal mod $nCols)"/>
            <table bgcolor="snow" border="1" cellpadding="5" cellspacing="2" borderColor="darkorange"
                style="font-size:9pt">
                <!-- 對於不需要補齊的行數,直接輸出 -->
                <xsl:for-each select="/Items/Item[position() &lt; $nNotProcessedRow +1]">
                <xsl:if test="position() mod $nCols = 1">
                <xsl:value-of select="$strTrLeft" disable-output-escaping="yes"/>
                </xsl:if>
                <td>
                <a target="_blank">
                <xsl:attribute name="href">
                <xsl:if test="contains(Url,'@')">mailto:</xsl:if><xsl:value-of select="Url"/></xsl:attribute>
                <xsl:value-of select="Title"/>
                </a>
                </td>
                <xsl:if test="position() mod $nCols = 0">
                <xsl:value-of select="$strTrRight" disable-output-escaping="yes"/>
                </xsl:if>
                </xsl:for-each>
                <!-- 轉換除去不需要補齊的記錄的剩余記錄 -->
                <xsl:if test="$nLefted != 0 and $nLefted != $nCols">
                <xsl:value-of select="$strTrLeft" disable-output-escaping="yes"/>
                <xsl:for-each select="/Items/Item[position() &gt;$nNotProcessedRow]">
                <td>
                <a target="_blank">
                <xsl:attribute name="href">
                <xsl:if test="contains(Url,'@')">mailto:</xsl:if><xsl:value-of select="Url"/></xsl:attribute>
                <xsl:value-of select="Title"/>
                </a>
                </td>
                </xsl:for-each>
                <!--
                如果nLefted不等於0和列數,則需要進行補齊,這裡進行遞歸調用,需要傳遞的參數有兩個:
                nLefted:要補齊的列數;
                nCols:表格的列數。
                -->
                <xsl:call-template name="MyFun">
                <xsl:with-param name="nLefted" select="$nLefted"/>
                <xsl:with-param name="nCols" select="$nCols"/>
                </xsl:call-template>
                <xsl:value-of select="$strTrRight" disable-output-escaping="yes"/>
                </xsl:if>
            </table>
            <p>共有<xsl:value-of select="$nTotal"/>條數據。</p>
            </xsl:template>
            <xsl:template name="MyFun">
            <xsl:param name="nLefted"/>
            <xsl:param name="nCols"/>
            <xsl:if test=" $nLefted != 0 and $nLefted != $nCols">
            <td>
            <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
            </td>
            <xsl:call-template name="MyFun">
            <xsl:with-param name="nLefted" select="$nLefted - 1"/>
            <xsl:with-param name="nCols" select="$nCols"/>
            </xsl:call-template>
            </xsl:if>
            </xsl:template>
            </xsl:stylesheet>           
由於http://www.w3.org/1999/XSL/Transform名稱控件只有IE5.5+才支持,為了使我們的代碼具有通用性,我們在服務器端進行轉換,首先建立GoodLoop.ASPx如下:

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="GoodLoop.ASPx.vb"
            Inherits="ASPxWeb.mengxianhui.com.GoodLoop"%>
            <%@ Import NameSpace = "System" %>
            <%@ Import NameSpace = "System.XML" %>
            <%@ Import NameSpace = "system.XML.Xsl" %>
            <!doctype HTML PUBLIC "-//W3C//DTD Html 4.0 Transitional//EN">
            <Html>
                <head>
                    <title>GoodLoop</title>
                    <meta content="Microsoft Visual Studio .Net 7.0" name="GENERATOR">
                    <meta content="Visual Basic 7.0" name="CODE_LANGUAGE">
                    <meta content="JavaScript" name="vs_defaultClIEntScript">
                    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
                    <script runat=Server>
                    Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs)
                    Try
XMLDocument()
                    Xmldom.Load(Server.MapPath("GoodLoop.XML"))
                    Dim trans As XslTransform = New XslTransform()
                    trans.Load(Server.MapPath("GoodLoop.xsl"))
                    Xml1.Document = XMLdom
                    XML1.Transform = trans
                    Catch er As XMLException
                    Label1.Text = er.Message
                    End Try
                    End Sub
                    </script>
                </head>
                <body MS_POSITIONING="GridLayout">
                    <form id="Form1" method="post" runat="server">
                        <asp:label id="Label1" runat="server"></ASP:label>
                        <asp:xml id="XML1" runat="server"></ASP:XML>
                    </form>
                </body>
            </Html>           
本文中所使用的XML數據樣式為:GoodLoop.XML

<?XML version="1.0" encoding="UTF-8"?>
            <?XML-stylesheet type="text/xsl" href="GoodLoop1.xsl"?>
            <items>
            <item>
            <url>http://XML.sz.luohuedu.Net</url>
            <title>【孟憲會之精彩世界】</title>
            </item>
            <item>
            <url>http://lucky.myrice.com/</url>
            <title>【孟憲會之精彩世界】</title>
            </item>
            ...............................
            </items>
           
轉換結果如下:

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved