dbaker6
dbaker6

Reputation: 39

How do I Sort in XSL?

I'm trying to change the order of some elements on a page.

http://ccri.edu/laws/faculty_staff/

You'll notice if you hit the "Complete Listing" button that the order is Adjunct Faculty, Staff, Faculty... I'm trying to get it display Faculty, Adjunct Faculty, Staff.

The faculty & Staff are pulled into the page from an xml sheet which looks like this

    <Persons>
  <Person>
    <Name><Last>Abatiello</Last>
    <First>Steven</First></Name>
    <Role>Staff</Role>
    <Title>Assistant Coordinator</Title>
    <Department>Student Success Center</Department>
    <Campus>Liston Campus</Campus>
    <Office>2236</Office>
    <Email>smabatiello&#64;ccri.edu</Email>
    <Telephone>555-5555</Telephone>
    <Website></Website>
  </Person>
  <Person>
    <Name><Last>Abbate</Last>
    <First>Maureen</First></Name>
    <Role>Faculty</Role>
    <Title>Professor</Title>
    <Department>English</Department>
    <Campus>Liston Campus</Campus>
    <Office></Office>
    <Email>bate&#64;ccri.edu</Email>
    <Telephone>555-5555</Telephone>
    <Website></Website>
  </Person>
</persons>

paired up with XSL to display it

  <xsl:when test="$department-filter != ''">
  <xsl:for-each-group select="$doc/Persons/Person[lower-case(Department) = tokenize(lower-case($department-filter),',')]" group-by="Role">
    <p><span class="facultyheader"><xsl:value-of select="current-grouping-key()"/>:&nbsp;</span>
      <xsl:for-each select="current-group()">
        <xsl:choose>
          <xsl:when test="position() != last()">
            <xsl:value-of select="concat(Name/First, ' ', Name/Last)"/>,&nbsp;
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat(Name/First, ' ', Name/Last)"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </p>
  </xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
  <xsl:for-each-group select="$doc/Persons/Person" group-by="Role">
    <p><span class="facultyheader"><xsl:value-of select="current-grouping-key()"/>:&nbsp;</span>
      <xsl:for-each select="current-group()">
        <xsl:choose>
          <xsl:when test="position() != last()">
            <xsl:value-of select="concat(Name/First, ' ', Name/Last)"/>,&nbsp;
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="concat(Name/First, ' ', Name/Last)"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </p>
  </xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>

So right now its being sorted alphabetically... I know I have to edit the XSL I'm just to sure what to edit. Any Ideas? Thanks!

Upvotes: 0

Views: 44

Answers (1)

Michael Kay
Michael Kay

Reputation: 163595

The order in which the groups are processed is determined by the xsl:sort child of xsl:for-each-group

<xsl:for-each-group select="..." group-by="Role">
  <xsl:sort select="...."/>

That leaves the question of what sort key to use. For this kind of thing the best approach is to have a function:

<xsl:function name="f:role-rank" as="xs:integer">
  <xsl:param name="role" as="xs:string"/>
  <xsl:sequence select="index-of(('Faculty', 'Adjunct-Faculty', 'Staff'), $role)"/>
</xsl:function>

and then

<xsl:sort select="f:role-rank(current-grouping-key())"/>

You could also invoke index-of directly in xsl:sort/@select but this gives a little bit of abstraction.

Upvotes: 1

Related Questions