XSLT Position()

I have the following XML data, and process HTML using XSLT processor.

<?xml version="1.0" encoding="utf-16"?>
<ScorecardSummary>
  <DivisionSummary>
    <DivisionName>
      <string> SYSTEM</string>
    </DivisionName>
    <ScorecardSummaryByDivision>
      <ScorecardSummaryByKPI>
        <Header>
          <string>Committed Time of Arrival</string>
          <string>Goal</string>
          <string>1D</string>
          <string>7D</string>
          <string>QTD</string>
          <string>YTD</string>
          <string>YTD Event Cars</string>
        </Header>
        <Data>
          <ScorecardContract>
            <TypeName>System</TypeName>
            <Goal>68</Goal>
            <GoalWarning>64.6</GoalWarning>
            <TotalCountYear>1234</TotalCountYear>
            <Value1D>79</Value1D>
            <Value7D>79.2</Value7D>
            <ValueQTD>79.1</ValueQTD>
            <ValueYTD>73.3</ValueYTD>
          </ScorecardContract>
          <ScorecardContract> 
             <!-- more data -->
          </ScorecardContract>
       </Data>
      </ScorecardSummaryByKPI>
      <ScorecardSummaryByKPI>
         <!-- more data -->
     </ScorecardSummaryByKPI>
    </ScorecardSummaryByDivision>
  </DivisionSummary>
</ScorecardSummary>

I create tables according to the Data section of ScorecardSummaryByKPI part, and the headers of the tables match the Header section of ScorecardSummaryByKPI part.

Here is the XSL:

<?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"/>

<xsl:template match="/">
  <html>
    <body>
        <xsl:apply-templates select="ScorecardSummary/DivisionSummary">
        </xsl:apply-templates>
    </body>
  </html>
</xsl:template>

<xsl:template match="ScorecardSummary/DivisionSummary/DivisionName">
  <h1>
    <xsl:value-of select="current()/string"/>
  </h1>
</xsl:template>

<xsl:template match="ScorecardSummaryByDivision">
  <xsl:apply-templates select="current()/ScorecardSummaryByKPI"/>
</xsl:template>

<xsl:template match="ScorecardSummaryByKPI">
  <table border="1" cellspacing="0" cellpadding="5">
    <xsl:apply-templates select="current()/Header"/>
    <xsl:apply-templates select="current()/Data"/>
  </table>
</xsl:template>

<xsl:template match="Header">
  <tr>
    <TH bgcolor="#000066" width="250" height="30" style="color:white">
      <xsl:value-of select="string[1]"/>
    </TH>
    <TH bgcolor="#000066" height="30" style="color:white">
      <xsl:value-of select="string[2]"/>
    </TH>
    <TH bgcolor="#000066" height="30" style="color:white">
      <xsl:value-of select="string[3]"/>
    </TH>
    <TH bgcolor="#000066" height="30" style="color:white">
      <xsl:value-of select="string[4]"/>
    </TH>
    <TH bgcolor="#000066" height="30" style="color:white">
      <xsl:value-of select="string[5]"/>
    </TH>
    <TH bgcolor="#000066" height="30" style="color:white">
      <xsl:value-of select="string[6]"/>
    </TH>
  </tr>
</xsl:template>

<xsl:template match="Data">
  <xsl:for-each select="current()/ScorecardContract">
    <xsl:variable name="i" select="position()"/>
    <tr>
      <xsl:apply-templates select="TypeName"/>
      <xsl:apply-templates select="Goal"/>
      <xsl:apply-templates select="Value1D"/>
      <xsl:apply-templates select="Value7D"/>
      <xsl:apply-templates select="ValueQTD"/>
      <xsl:apply-templates select="ValueYTD"/>
    </tr>
  </xsl:for-each>
</xsl:template>

<xsl:template match="TypeName">
  <xsl:choose>
    <xsl:when test="self::node()[text()='System'] | self::node()[text()='Checkpoint']">
      <td bgcolor="lightgray" style="font-weight:bold">
        <xsl:value-of select="."/>
      </td>
    </xsl:when>
    <xsl:otherwise>
      <td>
        <xsl:value-of select="."/>
      </td>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="Goal">
  <td bgcolor="lightgray">
    <xsl:value-of select="format-number(.,'###,##%')"/>
  </td>
</xsl:template>

<xsl:template match="Value1D">
  <xsl:choose>
    <xsl:when test="position() != 3"> <!-- Here where I went wrong -->
      <td bgcolor="lightgreen"><xsl:value-of select="."/></td>
    </xsl:when>
    <xsl:otherwise>
      <td bgcolor="green">
        <xsl:value-of select="."/>
      </td>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="Value7D">
  <td bgcolor="lightgreen"><xsl:value-of select="."/></td>
</xsl:template>

<xsl:template match="ValueQTD">
  <td bgcolor="lightgreen"><xsl:value-of select="."/></td>
</xsl:template>

<xsl:template match="ValueYTD">
  <td bgcolor="lightgray"><xsl:value-of select="."/></td>
</xsl:template>

</xsl:stylesheet>

Totally 6 tables are generated. My question is:

How can I mark the tables, in order to generate different styles? For example how to change styles for the third table?

Answers


As the template for the parent element just applies templates to ScorecardSummaryByKPI elements you can use position() to refer to the ordering of these elements.

<xsl:template match="ScorecardSummaryByKPI">
  <table border="1" cellspacing="0" cellpadding="5">
<xsl:if test="position()=3">
   <xsl:attribute name="class">something</xsl:attribute>
</xsl:if>
    <xsl:apply-templates select="Header"/>
    <xsl:apply-templates select="Data"/>
  </table>
</xsl:template>

adds class="something" to the third table. Note I removed the current()/ You can remove them all, they do nothing useful.


Need Your Help

Use jQuery to create numbered list with styled numbers?

jquery css html-lists

I need to create what looks like an ordered list with colored numbers in a Wordpress site.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.