开发者

XML Generate Columns by Group using XSLT

I am trying to generate a 4 column directory, grouped by the 4 disciplines in my department. One XML file contains the entire group. Each element has a department tag. The construction of the directory would be the following:

Group each entry by discipline.

For each group, cycle through each entry. If the Rank equals Supervisor, fill out the supervisor DIV, otherwise keep generating a div for each person in the group. Once all entries in the group are exhausted, construct the next column for the next group... Keep going until all groups are exhausted.

I'm new to XSLT and really need help. I can create a key for each group, and cycle through the entries in the group, but I'm not sure how to cycle through the different groups.

My mark up is below.

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="group" match="employee" use="dept" />


<xsl:template match="/">

<div id="directory">    
    <div class="man">
        <h1>Manager</h1>
        <h2>John Doe</h2>
    </div>


    <div class="group">
<xsl:for-each select="key('group', 'Mechanical')">
<xsl:sort select="name" order="ascending"/>

                (I need a conditional here to check if rank = supervisor)
        <div class="super">
            <h1>Supervisor</h1>
            <h2><xsl:value-of select="name"/></h2>
        </div>

            <div>
                <p class="name"><xsl:value-of select="name"/></p>
                                    <p class="ID"><xsl:value-of select="id"/></p>

            </div>
  </xsl:for-each>
</div>

XML Directory

<?xml version="1.0" encoding="ISO-8859-1" ?> 

<directory>
  <employee>
    <dept></dept>
    <rank>Manager</rank>
    <name>John Doe</name>
    <id>1234</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>Supervisor</rank>
    <name>Jane Doe</name>
    <id>4321</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee> 
  <employee>
    <dept>Civil</dept>
    <rank>Supervisor</rank>
    <name>Jane Doe</name>
    <id>4321</id>
  </employee>
  <employee>
    <dept>Civil</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
  <employee>
    <dept>Civil</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>Supervisor</rank>
    <name>Jane Doe</name>
    <id>4321</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
 </directory>

Output would look something like:

XML Generate Columns by Group using XSLT

HTML should look something like:

<div id="directory">    
<div class="man">
<h1>Manager</h1>
<h2>John Doe</h2>
</div>
<div class="group">
    <div class="super">
        <h1>Mechanical Supervisor</h1>
        <h2>Supervisor Name</h2>
    </div>
    <div>
        <p class="name">Mech employee name</p>
                    <p class="ID">Mech employee ID</p>
</div><!--end group A-->

<div class="group">
    <div class="super">
        <h1>CivilSupervisor</h1>
        <h2>Supervisor Name</h2>
    </div>
    <div>
        <p class="name">Civil employee name</p>
                    <p class="ID">Civil employee ID</p>
</div><!--end group B-->

<div class="group">
    <div class="super">
        <h1>Electrical Supervisor</h1>
        <h2>Supervisor Name</h2&g开发者_高级运维t;
    </div>
    <div>
        <p class="name">Electrical employee name</p>
                    <p class="ID">Electrical employee ID</p>
</div><!--end group C-->
</div>


This XSLT 1.0 transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kEmpByDeptRank" match="employee"
          use="concat(dept,'+', rank)"/>

 <xsl:key name="kEmpByDept" match="employee"
          use="dept"/>

 <xsl:template match="directory">
   <div id="directory">
     <xsl:apply-templates select=
      "key('kEmpByDeptRank', '+Manager')"/>
      <xsl:apply-templates select=
        "employee[not(rank='Manager')]"/>
   </div>
 </xsl:template>

 <xsl:template match=
  "employee[generate-id()
           =
            generate-id(key('kEmpByDept', dept)[1])
           ]
  ">
  <div class="group">
    <xsl:apply-templates mode="inGroup" select=
    "key('kEmpByDeptRank', concat(dept,'+Supervisor'))"/>

    <xsl:apply-templates mode="inGroup" select=
      "key('kEmpByDept', dept)[not(rank='Supervisor')]"/>
  </div>
 </xsl:template>

 <xsl:template match="employee[rank='Manager']">
   <div class="man">
     <h1>Manager</h1>
     <h2><xsl:value-of select="name"/></h2>
   </div>
 </xsl:template>

 <xsl:template match="employee[rank='Supervisor']"
      mode="inGroup">
    <div class="super">
      <h1>
        <xsl:value-of select="concat(dept, ' Supervisor')"/>
      </h1>
      <h2><xsl:value-of select="name"/></h2>
    </div>
 </xsl:template>

 <xsl:template match="employee" mode="inGroup">
   <div>
     <p class="name">
       <xsl:value-of select="concat(dept, ' ', name)"/>
     </p>
     <p class="ID">
       <xsl:value-of select="concat(dept, ' ', id)"/>
     </p>
   </div>
 </xsl:template>
 <xsl:template match="employee"/>
</xsl:stylesheet>

when applied on this XML document (similar to the provided one, but changed the names and Ids to be distinct):

<directory>
  <employee>
    <dept></dept>
    <rank>Manager</rank>
    <name>John Doe</name>
    <id>1234</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>Supervisor</rank>
    <name>Jane Doe</name>
    <id>4321</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>General</rank>
    <name>Joe Doe</name>
    <id>2314</id>
  </employee>
  <employee>
    <dept>Mechanical</dept>
    <rank>General</rank>
    <name>Jim Smith</name>
    <id>2315</id>
  </employee>
  <employee>
    <dept>Civil</dept>
    <rank>Supervisor</rank>
    <name>Ann Smith</name>
    <id>4322</id>
  </employee>
  <employee>
    <dept>Civil</dept>
    <rank>General</rank>
    <name>Peter Pan</name>
    <id>2316</id>
  </employee>
  <employee>
    <dept>Civil</dept>
    <rank>General</rank>
    <name>Mike Sims</name>
    <id>2317</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>Supervisor</rank>
    <name>Amy Dull</name>
    <id>4323</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>General</rank>
    <name>Dan Brown</name>
    <id>2318</id>
  </employee>
  <employee>
    <dept>Electrical</dept>
    <rank>General</rank>
    <name>John Kerry</name>
    <id>2319</id>
  </employee>
 </directory>

produces the wanted, correct result:

<div id="directory">
   <div class="man">
      <h1>Manager</h1>
      <h2>John Doe</h2>
   </div>
   <div class="group">
      <div class="super">
         <h1>Mechanical Supervisor</h1>
         <h2>Jane Doe</h2>
      </div>
      <div>
         <p class="name">Mechanical Joe Doe</p>
         <p class="ID">Mechanical 2314</p>
      </div>
      <div>
         <p class="name">Mechanical Jim Smith</p>
         <p class="ID">Mechanical 2315</p>
      </div>
   </div>
   <div class="group">
      <div class="super">
         <h1>Civil Supervisor</h1>
         <h2>Ann Smith</h2>
      </div>
      <div>
         <p class="name">Civil Peter Pan</p>
         <p class="ID">Civil 2316</p>
      </div>
      <div>
         <p class="name">Civil Mike Sims</p>
         <p class="ID">Civil 2317</p>
      </div>
   </div>
   <div class="group">
      <div class="super">
         <h1>Electrical Supervisor</h1>
         <h2>Amy Dull</h2>
      </div>
      <div>
         <p class="name">Electrical Dan Brown</p>
         <p class="ID">Electrical 2318</p>
      </div>
      <div>
         <p class="name">Electrical John Kerry</p>
         <p class="ID">Electrical 2319</p>
      </div>
   </div>
</div>

and it displays in the browser as:

Manager

John Doe

Mechanical Supervisor

Jane Doe

Mechanical Joe Doe

Mechanical 2314

Mechanical Jim Smith

Mechanical 2315

Civil Supervisor

Ann Smith

Civil Peter Pan

Civil 2316

Civil Mike Sims

Civil 2317

Electrical Supervisor

Amy Dull

Electrical Dan Brown

Electrical 2318

Electrical John Kerry

Electrical 2319

Explanation: Muenchian method for grouping, and locating an employee (Manager or Supervisor) using a composite key (rank, department).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜