星期五, 七月 30, 2004

通过XSLT如何得到唯一的值(精彩例子)

Question:
1.一般在一组node()里得到唯一的代表node(),类似SQL Select Distinct 关键词的作用.
在XSLT是通过 node()[not(aixs=preceding::node/aixs)]类似的语法得到.

如:XML
<?xml version="1.0" encoding="UTF-8"?>
<xmldata>
<current_row>
<dept>70</dept>
<deptname>??部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB00660</empid>
<positioncode>490</positioncode>
<positiondesc>???</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>???</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>70</dept>
<deptname>??部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB10203</empid>
<positioncode>80</positioncode>
<positiondesc>文?</positiondesc>
<gradetype>10</gradetype>
<gradedesc>初?</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>??花</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>90</dept>
<deptname>人事部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB00404</empid>
<positioncode>50</positioncode>
<positiondesc>?堂</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>?定金</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>90</dept>
<deptname>人事部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB10196</empid>
<positioncode>90</positioncode>
<positiondesc>司机</positiondesc>
<gradetype>40</gradetype>
<gradedesc>??</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>???</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>100</dept>
<deptname>生?部</deptname>
<section>130</section>
<sectionname>??合B班</sectionname>
<empid>HMB00481</empid>
<positioncode>360</positioncode>
<positiondesc>普工</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>??秀</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>100</dept>
<deptname>生?部</deptname>
<section>130</section>
<sectionname>??合B班</sectionname>
<empid>HMB00891</empid>
<positioncode>360</positioncode>
<positiondesc>普工</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>邢巨芳</namechin>
<nameeng/>
</current_row>
</xmldata>

希望得到的结果如图:



最终得到的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
<html>
<head>
<title>ok</title>
</head>
<link href="ehrm.css" rel="stylesheet" type="text/css"/>
<body>
<xsl:text disable-output-escaping="yes">
<![CDATA[
<script>
function folder(referen,objname)
{
var localobj=findObj(objname);
if(localobj.style.display=='none')
{

localobj.style.display='';
referen.style.backgroundImage='url(../images/image2/opengroup.gif)';}else{

localobj.style.display='none';
referen.style.backgroundImage='url(../images/image2/group.gif)';
}
}

// Example: obj = findObj("image1");
function findObj(theObj, theDoc)
{
var p, i, foundObj;

if(!theDoc) theDoc = document;
if( (p = theObj.indexOf("?")) > 0 && parent.frames.length)
{
theDoc = parent.frames[theObj.substring(p+1)].document;
theObj = theObj.substring(0,p);
}
if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj];
for (i=0; !foundObj && i < theDoc.forms.length; i++)
foundObj = theDoc.forms[i][theObj];
for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
foundObj = findObj(theObj,theDoc.layers[i].document);
if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);

return foundObj;
}

</script>
]]>
</xsl:text>
<xsl:apply-templates select="//xmldata"/>
</body>
</html>
</xsl:template>

<xsl:template match="xmldata">
<div id="Layer3" style="position:absolute; width:412px; height:300px; z-index:3; top: 141px; overflow-y: scroll; left: 26px;">
<table width="400" border="0" cellspacing="0">
<xsl:for-each select="current_row[not(dept = preceding-sibling::current_row/dept)]">
<xsl:variable name="deptv" select="dept"/>
<tr>
<td class="folder1" onMouseUp="with(findObj('dept{position()}'))if(style.display=='none'){{style.display='';this.style.backgroundImage='url(../images/image2/opengroup.gif)'}}else{{style.display='none';this.style.backgroundImage='url(../images/image2/group.gif)'}}">
<xsl:value-of select="deptname"/>/<xsl:value-of select="dept"/>(<xsl:value-of select="count(/xmldata/current_row/section[preceding-sibling::dept=$deptv])"/>)
</td>
</tr>
<tr>
<td class="subfolder1" id="dept{position()}">
<table width="373" border="0" cellspacing="0">
<xsl:variable name="section_row" select="//current_row[ dept = $deptv and not(section=preceding-sibling::current_row[dept=$deptv]/section)]"/>
<!--section group-->
<xsl:for-each select="$section_row">
<tr>
<td width="371" class="folder1" onMouseUp="with(findObj('{$deptv}group{position()}'))if(style.display=='none'){{style.display='';this.style.backgroundImage='url(../images/image2/opengroup.gif)'}}else{{style.display='none';this.style.backgroundImage='url(../images/image2/group.gif)'}}">
<xsl:value-of select="current()/sectionname"/>/<xsl:value-of select="current()/section"/>
</td>
</tr>
<tr>
<!--sss-->
<td class="subfolder1" id="{$deptv}group{position()}">
<table width="350" border="0" cellspacing="0">
<!--Employee circle-->
<xsl:for-each select="/xmldata/current_row[dept = $deptv and sectionname=current()/sectionname]">
<tr>
<td width="66" class="file1" >
<xsl:choose>
<xsl:when test="not(namechin = 'null')">
<xsl:value-of select="namechin"/>
</xsl:when>
<xsl:when test="namechin = 'null' and not(nameeng = 'null')">
<xsl:value-of select="nameeng"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>NameNull</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td width="60" class="cao2" onMouseOver="this.style.fontWeight='600';this.style.cursor='hand'" onMouseOut="style.fontWeight='400'" onClick="openWindow('{empid}','','features');parclose()">
<xsl:value-of select="empid"/>
</td>
<td width="90" class="cao1">
<xsl:value-of select="gradedesc"/>
</td>
<td width="25" class="cao1">--</td>
<td width="55" class="cao1">
<xsl:value-of select="positiondesc"/>
</td>
<td width="42" class="cao1">
<xsl:value-of select="employmentstatusdesc"/>
</td>
</tr>
</xsl:for-each>
<!--Employee circle over-->
</table>
</td>
<!--sss-->
</tr>
</xsl:for-each>
<!--section group over-->

</table>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>
</xsl:stylesheet>