DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 把XML的數據轉換成多列表格形式
把XML的數據轉換成多列表格形式
編輯: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>
 轉換結果如下圖所示:

把XML的數據轉換成多列表格形式

  但是,從上面的結果圖可以看出,如果數據記錄不是表格列數的整數倍的時候,最後一行的最後幾列不會生成出來,即在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 < $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 < ($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="'<tr>'"/>
  <xsl:variable name="strTrRight" select="'</tr>'"/>
  <!-- 計算總記錄數 -->
  <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() < $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() >$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">&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
  Dim Xmldom As New 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的數據轉換成多列表格形式



 

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