Xml – How to dynamically get value of a row using XSLT

xmlxslt

I have to create one table using XSLT and CSS. The table should look like:

ID    FNAME
1    AA
2    BB

My XML is:

<students>
  <studentDetails>
    <id>1</id>
    <fname>AA</fname>
  </studentDetails>
  <studentDetails>
    <id>2</id>
    <fname>BB</fname>
  </studentDetails>
<students>

And here my XSLT so far:

<xsl:template match="students">
  <div>
    <div class="idcol">
      <div class="header">
        <xsl:text>ID</xsl:text>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[1]/id"/>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[2]/id"/>
      </div>
    </div>
    <div class="fnamecol">
      <div class="header">
        <xsl:text>FNAME</xsl:text>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[1]/fname"/>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[2]/fname"/>
      </div>
    </div>
  </div>
</xsl:template>

The output looks right after applying CSS, but the problem is that I have used [1] and [2] directly. So if there is 3rd row then I have to change my code again. How to do this dynamically using some index – can somebody help?

Best Answer

You could use <xsl:for-each>, but I think this is more concise, and extensible to arbitrarily many columns (so long as they're all the same):

<xsl:stylesheet version="1.0" xmlns:xs="...">

  <xsl:template match="students">
    <div>
      <div class="idcol">
        <div class="header">
          <xsl:text>ID</xsl:text>
        </div>
        <xsl:apply-templates>
          <xsl:with-param name="child-name" select="'id'"/>
        </xsl:apply-templates>
      </div>
      <div class="fnamecol">
        <div class="header">
          <xsl:text>FNAME</xsl:text>
        </div>
        <xsl:apply-templates>
          <xsl:with-param name="child-name" select="'fname'"/>
        </xsl:apply-templates>
      </div>
    </div>
  </xsl:template>

  <xsl:template match="studentDetails">
    <xsl:param name="child-name"/>
    <div class="row">
      <xsl:value-of select="*[name() = $child-name]"/>
    </div>
  </xsl:template>

</xsl:stylesheet>
Related Topic