Question

I have the following XML:

<record>
  <fruit>Apples</fruit>
  <fruit>Oranges</fruit>
  <fruit>Bananas</fruit>
  <fruit>Plums</fruit>
  <vegetable>Carrots</vegetable>
  <vegetable>Peas</vegetable>
  <candy>Snickers</candy>
</record>

and the following XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="4.0" encoding="iso-8859-1"  indent="yes" />
<xsl:key name="nodes-by-name" match="*" use="name()"/>
<xsl:template match="*">
  <table class="fieldGrid" border="0">
    <xsl:for-each select="*">
      <xsl:if test="not(*)">
        <xsl:if test=".!=''''">
          <xsl:call-template name="lowestLevel"/>
        </xsl:if>
        <xsl:if test=".=''''">
          <xsl:call-template name="hasChildren"/>
        </xsl:if>
      </xsl:if>
      <xsl:if test="*">
        <xsl:call-template name="hasChildren"/>
      </xsl:if>
    </xsl:for-each>
  </table>
</xsl:template>

<xsl:template name="lowestLevel">
  <tr class="fields">
    <td class="fieldName">
      <xsl:value-of select="translate(local-name(), ''_'', '' '')" />
    </td>
    <td class="fieldValue">
      <xsl:value-of select="translate(., ''_'', '' '')" />
    </td>
  </tr>
</xsl:template>

  <xsl:template name="hasChildren">
    <tr>
      <td colspan="2" class="sectionTitle">
        <xsl:value-of select="translate(local-name(), ''_'', '' '')" />&#160;<xsl:value-of select="count(key(''nodes-by-name'', name()))" />
      </td>
    </tr>
    <tr>
      <td>
        <xsl:for-each select="*">
          <xsl:if test="not(*)">
             <xsl:call-template name="lowestLevel"/>
           </xsl:if>
           <xsl:if test="*">
            <xsl:call-template name="hasChildren"/>
          </xsl:if>
        </xsl:for-each>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

The problem that I'm having is I get the following output where the number is the sum of the nodes with the same name, not the occurance of this node verses the other nodes with the same name. (I have simplified the html to remove the classes):

<table class="fieldGrid" border="0">
  <tr>
    <td>fruit 4</td>
    <td>Apples</td>
  </tr>
  <tr>
    <td>fruit 4</td>
    <td>Oranges</td>
  </tr>
  <tr>
    <td>fruit 4</td>
    <td>Bananas</td>
  </tr>
  <tr>
    <td>fruit 4</td>
    <td>Plums</td>
  </tr>
  <tr>
    <td>vegetable 2</td>
    <td>Carrots</td>
  </tr>
  <tr>
    <td>vegetable 2</td>
    <td>Peas</td>
  </tr>
  <tr>
    <td>candy 1</td>
    <td>Snickers</td>
  <tr>
</table>

I can't seem to figure out how to get the right selector to set the number as the occurance number of the field. It needs to be dynamic because the number of nodes in the record field can be upwards of 100 and I don't want to manually set it for all of the possible records. What I would like as a result is the following:

<table class="fieldGrid" border="0">
  <tr>
    <td>fruit 1</td>
    <td>Apples</td>
  </tr>
  <tr>
    <td>fruit 2</td>
    <td>Oranges</td>
  </tr>
  <tr>
    <td>fruit 3</td>
    <td>Bananas</td>
  </tr>
  <tr>
    <td>fruit 4</td>
    <td>Plums</td>
  </tr>
  <tr>
    <td>vegetable 1</td>
    <td>Carrots</td>
  </tr>
  <tr>
    <td>vegetable 2</td>
    <td>Peas</td>
  </tr>
  <tr>
    <td>candy 1</td>
    <td>Snickers</td>
  <tr>
</table>

Thank you

Was it helpful?

Solution

Input:

<record>
    <fruit>Apples</fruit>
    <fruit>Oranges</fruit>
    <fruit>Bananas</fruit>
    <fruit>Plums</fruit>
    <vegetable>Carrots</vegetable>
    <vegetable>Peas</vegetable>
    <candy>Snickers</candy>
</record>

XSLT:

<xsl:template match='record'>
    <table class='fieldGrid' border='0'>
        <xsl:for-each select='*'>
            <tr>
                <td>
                    <xsl:value-of select='local-name()'/>
                    <xsl:text> </xsl:text>
                    <xsl:number/>
                </td>
                <td><xsl:value-of select='.'/></td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

Output:

<table border="0" class="fieldGrid">
    <tr>
        <td>fruit 1</td>
        <td>Apples</td>
    </tr>
    <tr>
        <td>fruit 2</td>
        <td>Oranges</td>
    </tr>
    <tr>
        <td>fruit 3</td>
        <td>Bananas</td>
    </tr>
    <tr>
        <td>fruit 4</td>
        <td>Plums</td>
    </tr>
    <tr>
        <td>vegetable 1</td>
        <td>Carrots</td>
    </tr>
    <tr>
        <td>vegetable 2</td>
        <td>Peas</td>
    </tr>
    <tr>
        <td>candy 1</td>
        <td>Snickers</td>
    </tr>
</table>

OTHER TIPS

you must use

<xsl:value-of select="position()"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top