Mottie
Mottie

Reputation: 86453

Getting an attribute via another attribute in XSL

I stink at XSLT, so I'm not sure how to approach this... I'm getting a feed from the EQ2 database. The XML looks like this:

<guilds limit="1" returned="1">
  <guild accounts="3" alignment="0" dateformed="1127855265" guildid="111" guildstatus="0" id="1111111111" last_update="1326986410" level="11" name="MyGuild" version="1" world="Permafrost" worldid="202">
    <ranks>
      <rank id="0" name="Leader"/>
      <rank id="1" name="Senior Officer"/>
      <rank id="2" name="Officer"/>
      <rank id="3" name="Senior Member"/>
      <rank id="4" name="Member"/>
      <rank id="5" name="Junior Member"/>
      <rank id="6" name="Initiate"/>
      <rank id="7" name="Recruit"/>
    </ranks>
    <members>
      <member dbid="123456" rank="0" name="Dude1"/>
      <member dbid="123457" rank="1" name="Dude2"/>
      <member dbid="123458" rank="2" name="Dude3"/>
      <member dbid="123459" rank="4" name="Dude4"/>
      <member dbid="123460" rank="4" name="Dude5"/>
      <member dbid="123461" rank="4" name="Dude6"/>
    </members>
    <events/>
  </guild>
</guilds>

I'm trying to add the ranks into a table. The XSL (version 1) snippet for it is as follows, but adding the name from the rank isn't working properly - I know this part is wrong:

<xsl:value-of select="rank/rank[@id=1]/@name"/>

So, can I get some help making it work and maybe an idea of how to shorten it?

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" indent="yes"/>
<xsl:template match="/">

<table width="100%" cellspacing="0" cellpadding="0" id="eq2roster" align="center">
 <thead>
  <tr>
   <td colspan="4" class="eq2CharacterHeader">Character</td>
   <td colspan="3" class="eq2TradeskillsHeader">Tradeskills</td>
  </tr>
  <tr class="ForumCategoryHeader">
   <th class="eq2NameHeader">Name</th>
   <th class="eq2RankHeader">Rank</th>
   <th class="eq2ClassHeader">Class</th>
   <th class="eq2LevelHeader">Level</th>
   <th class="eq2ArtisanHeader">Artisan</th>
   <th class="eq2ArtisanLevelHeader">Level</th>
   <th class="eq2SecondaryHeader">Secondary</th>
  </tr>
 </thead>
 <tbody>
  <xsl:for-each select="guilds/guild/members/member">
   <xsl:if test="@id &gt; 1">
   <tr>
    <td class="eq2Name">
     <xsl:element name="a">
      <xsl:attribute name="href">
       <xsl:text>http://eq2players.station.sony.com/</xsl:text>
       <xsl:value-of select="concat(normalize-space(/guilds/guild/@world), '/')"/>
       <xsl:value-of select="concat(normalize-space(@name), '/')"/>
      </xsl:attribute>
      <xsl:attribute name="target">
       <xsl:text>_blank</xsl:text>
      </xsl:attribute>
      <xsl:value-of select="normalize-space(@name)"/>
     </xsl:element>
    </td>

    <xsl:element name="td">
     <xsl:attribute name="class">
      <xsl:text>eq2Rank eq2rank-</xsl:text>
      <xsl:value-of select="translate(normalize-space(guild/@rank),' ','')"/>
     </xsl:attribute>

       <xsl:choose>
         <xsl:when test="member/@rank = 1"><span class = "rank1"><xsl:value-of select="ranks/rank[@id=1]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 2"><span class = "rank2"><xsl:value-of select="ranks/rank[@id=2]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 3"><span class = "rank3"><xsl:value-of select="ranks/rank[@id=3]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 4"><span class = "rank4"><xsl:value-of select="ranks/rank[@id=4]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 5"><span class = "rank5"><xsl:value-of select="ranks/rank[@id=5]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 6"><span class = "rank6"><xsl:value-of select="ranks/rank[@id=6]/@name"/></span></xsl:when>
         <xsl:when test="member/@rank = 7"><span class = "rank7"><xsl:value-of select="ranks/rank[@id=7]/@name"/></span></xsl:when>
        </xsl:choose>

    </xsl:element>

    <xsl:element name="td">
     <xsl:attribute name="class">
      <xsl:text>eq2Class eq2</xsl:text>
      <xsl:value-of select="translate(normalize-space(type/@class),' ','')"/>
     </xsl:attribute>
    <xsl:value-of select="type/@class"/>
    </xsl:element>

    <td class="eq2level"><xsl:value-of select="type/@level"/></td>

    <xsl:element name="td">
     <xsl:attribute name="class">
      <xsl:text>eq2ArtisanClass eq2</xsl:text>
      <xsl:value-of select="translate(normalize-space(tradeskills/tradeskill/@class),' ','')"/>
     </xsl:attribute>
    <xsl:value-of select="tradeskills/tradeskill/@class"/>
    </xsl:element>

    <td class="eq2ArtisanLevel"><xsl:value-of select="tradeskills/tradeskill/@level"/></td>

    <xsl:element name="td">
     <xsl:attribute name="class">
      <xsl:text>eq2Secondary eq2</xsl:text>
      <xsl:value-of select="translate(normalize-space(secondarytradeskills/secondarytradeskill/@name),' ','')"/>
     </xsl:attribute>
    <xsl:value-of select="secondarytradeskills/secondarytradeskill/@name"/>
    </xsl:element>

   </tr>
   </xsl:if>
  </xsl:for-each>
 </tbody>
</table>

</xsl:template>
</xsl:stylesheet>

Upvotes: 1

Views: 1097

Answers (3)

Wayne
Wayne

Reputation: 60424

The following expression associates a member with its corresponding rank using current() (assuming that the context node is the member in question):

../../ranks/rank[@id=current()/@rank]/@name

Full example:

<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:template match="member">
        <td class="eq2Rank eq2rank-{guild/@rank}">
            <span class="rank{@rank}">
                <xsl:value-of 
                    select="../../ranks/rank[@id=current()/@rank]/@name"/>
            </span>
        </td>
    </xsl:template>
</xsl:stylesheet>

Output (based on the originally posted sample XML):

<td class="eq2Rank eq2rank-">
   <span class="rank0">Leader</span>
</td>
<td class="eq2Rank eq2rank-">
   <span class="rank1">Senior Officer</span>
</td>
<td class="eq2Rank eq2rank-">
   <span class="rank2">Officer</span>
</td>
<td class="eq2Rank eq2rank-">
   <span class="rank4">Member</span>
</td>
<td class="eq2Rank eq2rank-">
   <span class="rank4">Member</span>
</td>
<td class="eq2Rank eq2rank-">
   <span class="rank4">Member</span>
</td>

Upvotes: 1

refextu
refextu

Reputation: 116

I'm not really sure if I get the question.

Asume that you have the right rankid you probably want to use variable

<xsl:variable name="rank" select="translate(normalize-space(guild/@rank),' ','')"/>

<span class = "rank{$rank}"><xsl:value-of select="ranks/rank[@id = $rank]/@name"/></span>

Upvotes: 1

Hasteur
Hasteur

Reputation: 462

Not sure if you can do something like this but it might be worth a shot. In the context of a single member

<xsl:value = "//ranks/rank[@id = ./@rank]/@name"/>

It uses X-Path to jump to the top and look for the ranks node, find the rank element whose ID attribute equals the rank attribute of the member, and grabs the name attribute

It's been a few years since I had to XSL like that, but should allow you to get rid of the XSL:choose block

Upvotes: 1

Related Questions