Friday, May 1, 2009

XSL 条件格式化

前言
在下的公司用Microsoft的SharePoint作为协作平台,各部门对系统的要求层出不穷,但大都可以归类为Record Management和搜索两方面。搜索方面我用得最多的是数据视图,而数据视图的数据是XML,显示格式化用的是XSLT。

SharePoint Designer (SPD)是可以处理的,Microsoft官方说明看起来你不用懂XSLT亦可以,在SPD点这点那,拖放一下就搞定。但是,当我用SPD来处理比较复杂的数据视图时候,经常出错,它生成的XSLT源码其实并不可靠,而且冗长。最理想的是,连好数据,带出需要字段后,所有的格式化手工处理。本文是有关条件格式化,不限于应用在SharePoint的数据视图,是可以应用于所有XSL。

实现
XSL 条件格式化,用<xsl:choose>可以实现。

Choose 是 XSL 的flow control 之一,按逻辑测试结果来执行特定代码,需要与 when 和 otherwise 一起使用,格式如下:
<xsl:choose>
  <xsl:when test="expression">
    ......
  </xsl:when>
  <xsl:otherwise>
    ......
  </xsl:otherwise>
</xsl:choose>

expression 是逻辑测试条件。<xsl:choose>与其他编程语言的switch很相似,choose内可以包含多个<xsl:when>,处理多个逻辑分支,而<xsl:otherwise>就处理各个when都不符合的情况,类似其他编程语言switch中的default。这是它与<xsl:if>的最大分别。

例子
以下是要显示的XML。连到一张名为new.xsl的XSL档。
<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="new.xsl"?>
<EMPDETAILS>
  <EMP EMPID="E001">
    <ENAME>Karen</ENAME>
    <DESG>MANAGER</DESG>
    <DEPT>SALES</DEPT>
    <SALARY>250</SALARY>
    <HP>http://www.baidu.com/</HP>
  </EMP>
  <EMP EMPID="E002">
    <ENAME>Lepton</ENAME>
    <DESG>Executive</DESG>
    <DEPT>MIS</DEPT>
    <SALARY>300</SALARY>
    <HP>http://leptonation.blogspot.com/</HP>
  </EMP>
</EMPDETAILS>


以下是new.xsl的源码,注意看<xsl:choose>部分:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="EMPDETAILS">
<html>
<body>
<table border="1" cellspacing="0">
<tr><td>EMPID</td><td>NAME</td><td>DESF</td><td>DEPT</td><td>SALARY</td><td>HP</td></tr>
<xsl:for-each select="EMP">

  <xsl:choose>
    <xsl:when test="SALARY &gt; 260">
      <tr style="color:red">
        <td><xsl:value-of select="@EMPID"/></td>
        <td><xsl:value-of select="ENAME"/></td>
        <td><xsl:value-of select="DESG"/></td>
        <td><xsl:value-of select="DEPT"/></td>
        <td><xsl:value-of select="SALARY"/></td>
      </tr>
    </xsl:when>

    <xsl:otherwise>
      <tr style="color:green">
        <td><xsl:value-of select="@EMPID"/></td>
        <td><xsl:value-of select="ENAME"/></td>
        <td><xsl:value-of select="DESG"/></td>
        <td><xsl:value-of select="DEPT"/></td>
        <td><xsl:value-of select="SALARY"/></td>
      </tr>
    </xsl:otherwise>
  </xsl:choose>

</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>


说明
1. <xsl:choose>的摆放位置,是在for-each之内,这是理所当然的,因为我这例子每个EMP我都要进行条件格式化
2. <xsl:when test="SALARY &gt; 260">这里,"SALARY &gt; 260"是条件,「>」符号要 html encode为「&gt;」,这里我设的条件是「SALARY大于260」
3. <xsl:when>与<xsl:otherwise>两组代码的唯一分别是<tr>的style,SALARY大于260的显示整行为红色,否则的话就显示整行为绿色
4. 用choose可以实现无限的可能,你要符合条件的单单更改SALARY元素的颜色亦可,你要把SALARY显示为超链接亦可,如下:
tr 的style不要,单单更改 SALARY的td...

<td style="color:red"><xsl:value-of select="SALARY"/></td>

或者把SALARY的值显示为超链接...

<td><a href="{HP}"><xsl:value-of select="SALARY"/></a></td>


《完》

No comments: