利用XML和XSL生成较为复杂的多表头表格

刚接手的项目有一查询页面,客户要求的实现格式较为复杂,需要达到合并多行多列的显示效果,由于只是一个小项目,客户方面不愿意引入太多外部的商业控件, 剩下的解决方案无外乎是:1.使用DataGrid; 2.使用SQL Reporting Services;3.自己合成html代码输出。

在 这些解决方案中,使用DataGrid的话,要达到合并行和列比较麻烦;而Reporting Services合并行和列相对简单,但因为显示结果的列数是动态的,这无论是写SQL和制作Reporting Services的rdl文件都是相当复杂的事。于是惟有通过生成自定义html代码的解决方法了。

在HTML代码中,要实现table元素的表和列合并主要是使用rowspan 和 colspan属性,比如要实现下面的格式输出,
服装颜色码组总数量
衬衫 SMLXLXXL  
710234 26

可采用以下的HTML代码:
None.gif < table  cellSpacing ="0"  cellPadding ="0"  border ="1"  bordercolor ="black"  style ="border-collapse:collapse" >
None.gif    
< tr  align ="center"  class ="titlebar" >
None.gif        
< td  width ="120" > 服装 </ td >
None.gif        
< td  width ="50" > 颜色 </ td >
None.gif        
< td  colspan ="6" > 码组 </ td >
None.gif        
< td  width ="50" > 总数量 </ td >
None.gif    
</ tr >
None.gif
None.gif    
< tr  align ="center" >
None.gif        
< td  rowspan ="2" > 衬衫 </ td >
None.gif        
< td  class ="sizebar" > &nbsp; </ td >
None.gif        
< td  width ="40"  class ="sizebar" > S </ td >
None.gif        
< td  width ="40"  class ="sizebar" > M </ td >
None.gif        
< td  width ="40"  class ="sizebar" > L </ td >
None.gif        
< td  width ="40"  class ="sizebar" > XL </ td >
None.gif        
< td  width ="40"  class ="sizebar" > XXL </ td >
None.gif        
< td  width ="40"  class ="sizebar" > &nbsp; </ td >                 
None.gif        
< td  class ="sizebar" > &nbsp; </ td >
None.gif    
</ tr >
None.gif    
< tr >
None.gif        
< td  align ="center" > </ td >
None.gif        
< td  align ="right" > 7 </ td >         
None.gif        
< td  align ="right" > 10 </ td >
None.gif        
< td  align ="right" > 2 </ td >
None.gif        
< td  align ="right" > 3 </ td >
None.gif        
< td  align ="right" > 4 </ td >
None.gif        
< td  align ="right" > &nbsp; </ td >                 
None.gif        
< td  align ="right" > 26 </ td >
None.gif    
</ tr >                         
None.gif
</ table >
要达到输出如此效果的HTML,而又不是在代码处进行硬编码,实现数据和页面输出的分离,XSL和XML结合自然就是不二之选了。通过从数据库中查询得到的结果集合生成指定格式的xml,然后通过预先写好的XSL结合,就可实现需要的效果。

之前并未接触太多的XSL方面的知识,只是有一个初步的理解,实际操作起来方知XSL这款所谓的“编程”语言,对于习惯既有编程语言模式的程序员而言可谓“噩梦”,很多的处理方法颠覆了既有的处理方法,有赖于强大的Google搜索引擎,方能勉强实现所要效果. 22.gif

附件( 下载)中的例子使用Vs.net 2003,只是一个简单的实现。XSL并不熟悉,写得较为凌乱,欢迎讨论。实现的效果可以参考下面的图:


附XSL文件
ContractedBlock.gif ExpandedBlockStart.gif WarehouseLayout.xsl
None.gif<?xml version="1.0" encoding="UTF-8"?>
None.gif
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
None.gif    
<xsl:variable name="SizeColWidth" select="40" />
None.gif
None.gif    
<xsl:template match="/Warehouse">    
None.gif        
<!-- Get the maxium in Size Columns  -->
None.gif        
<xsl:for-each select="Item/Color">
None.gif            
<xsl:sort select="count(Size)" order="descending"/>
None.gif            
<xsl:if test="position() = 1">    <!-- Only the first one will be executed  -->
None.gif              
<xsl:call-template name="show_table">
None.gif                
<xsl:with-param name="maxSizeCols" select="count(Size)" />
None.gif              
</xsl:call-template>                                
None.gif            
</xsl:if>
None.gif        
</xsl:for-each>
None.gif    
</xsl:template>
None.gif    
None.gif    
<xsl:template name="show_table">
None.gif      
<xsl:param name="maxSizeCols" />
None.gif        
<table cellSpacing="0" cellPadding="0" border="1" bordercolor="black" style="border-collapse:collapse">
None.gif            
<tr align="center" class="titlebar">
None.gif                
<td width="120">服装</td>
None.gif                
<td width="50">颜色</td>
None.gif                
<td colspan="{$maxSizeCols}">码组</td>
None.gif                
<td width="50">总数量</td>
None.gif            
</tr>
None.gif            
<xsl:for-each select="../../Item">
None.gif                
<xsl:if test="@name != ''">
None.gif                    
<xsl:variable name="colorCount" select="count(Color) + 1" />
None.gif                    
<tr align="center">
None.gif                        
<td rowspan="{$colorCount}"><xsl:value-of select="@name"></xsl:value-of></td>   <!-- 服装列  -->
None.gif                        
<td class="sizebar"></td>            <!--  颜色表头列  -->
None.gif                        
None.gif                        
<!-- 生成尺码表头列,不足的以空列补充 -->
None.gif                        
<xsl:for-each select="Color">
None.gif                            
<xsl:sort select="count(Size)" order="descending"/>
None.gif                            
<xsl:if test="position() = 1">
None.gif                                
<xsl:for-each select="Size">
None.gif                                    
<td width="{$SizeColWidth}" class="sizebar"><xsl:value-of select="@name"></xsl:value-of></td>
None.gif                                
</xsl:for-each>
None.gif                                
<xsl:call-template name="InsertBlankTD">
None.gif                                    
<xsl:with-param name="counter" select="$maxSizeCols - count(Size)" />
None.gif                                    
<xsl:with-param name="tdclass" select="'sizebar'" />
None.gif                                
</xsl:call-template>
None.gif                            
</xsl:if>
None.gif                        
</xsl:for-each>                                
None.gif                        
<td class="sizebar"></td>    <!-- 总数量表头列 -->
None.gif                        
None.gif                        
<xsl:for-each select="Color">
None.gif                            
<tr>
None.gif                                    
<td align="center"><xsl:value-of select="@name"></xsl:value-of></td>
None.gif                                    
<xsl:for-each select="Size">
None.gif                                        
<td align="right"><xsl:value-of select="text()"></xsl:value-of></td>
None.gif                                    
</xsl:for-each>
None.gif                                    
<xsl:call-template name="InsertBlankTD">
None.gif                                        
<xsl:with-param name="counter" select="$maxSizeCols - count(Size)" />
None.gif                                        
<xsl:with-param name="tdclass" select="''" />
None.gif                                    
</xsl:call-template>
None.gif                                    
<td align="right"><xsl:value-of select="@total"></xsl:value-of></td>
None.gif                            
</tr>
None.gif                        
</xsl:for-each>                                
None.gif                    
</tr>        
None.gif                
</xsl:if>                
None.gif            
</xsl:for-each>
None.gif    
None.gif        
</table>
None.gif    
</xsl:template>    
None.gif    
None.gif    
<xsl:template name="InsertBlankTD">
None.gif        
<xsl:param name="counter" />
None.gif        
<xsl:param name="tdclass" />     <!-- blank for no class-->
None.gif        
<xsl:if test="$counter &gt; 0">
None.gif            
<xsl:choose>
None.gif                
<xsl:when test="$tdclass = ''">
None.gif                    
<td />
None.gif                
</xsl:when>
None.gif                
<xsl:otherwise>
None.gif                    
<td width="{$SizeColWidth}" class="{$tdclass}" />
None.gif                
</xsl:otherwise>
None.gif            
</xsl:choose>
None.gif            
<xsl:call-template name="InsertBlankTD">
None.gif                
<xsl:with-param name="counter" select="$counter - 1" />
None.gif                
<xsl:with-param name="tdclass" select="$tdclass" />
None.gif            
</xsl:call-template>
None.gif        
</xsl:if>        
None.gif    
</xsl:template>    
None.gif    
None.gif    
None.gif
</xsl:stylesheet>
None.gif
None.gif  

示例XMLl文件
ContractedBlock.gif ExpandedBlockStart.gif XML Sample
None.gif<?xml version="1.0" encoding="UTF-8"?>
None.gif
<Warehouse>
None.gif    
<Item name="西服">
None.gif        
<Color name="黑" total="24">
None.gif            
<Size name="S">5</Size>
None.gif            
<Size name="M">4</Size>
None.gif            
<Size name="L">7</Size>
None.gif            
<Size name="XL">8</Size>
None.gif        
</Color>
None.gif        
<Color name="灰" total="10">
None.gif            
<Size name="S">5</Size>
None.gif            
<Size name="M">1</Size>
None.gif            
<Size name="L">4</Size>
None.gif            
<Size name="XL"/>
None.gif        
</Color>
None.gif    
</Item>
None.gif    
<Item name="衬衫">
None.gif        
<Color name="白" total="16">
None.gif            
<Size name="38">7</Size>
None.gif            
<Size name="39"></Size>
None.gif            
<Size name="40">2</Size>
None.gif            
<Size name="41">3</Size>
None.gif            
<Size name="42">4</Size>
None.gif        
</Color>
None.gif    
</Item>
None.gif    
<Item name="皮鞋">
None.gif        
<Color name="黑" total="15">
None.gif            
<Size name="7">1</Size>
None.gif            
<Size name="8">5</Size>
None.gif            
<Size name="9">5</Size>
None.gif            
<Size name="10">4</Size>
None.gif            
<Size name="11"/>
None.gif            
<Size name="12"/>
None.gif        
</Color>
None.gif        
<Color name="灰" total="13">
None.gif            
<Size name="7"/>
None.gif            
<Size name="8"/>
None.gif            
<Size name="9">5</Size>
None.gif            
<Size name="10">3</Size>
None.gif            
<Size name="11"/>
None.gif            
<Size name="12">5</Size>
None.gif        
</Color>
None.gif    
</Item>
None.gif
</Warehouse>
None.gif

转自:http://www.cnblogs.com/yeti/archive/2007/03/08/667117.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值