I have the structure:
<root>
<relation type="relation1">
<entityType1>a</entityType1>
<entityType2>1</entityType2>
<entityType2>2</entityType2>
<entityType2>3</entityType2>
</relation>
<relation type="relation2">
<entityType3>b</entityType3>
<entityType4>7</entityType4>
<entityType4>8</entityType4>
<entityType4>9</entityType4>
</relation>
<relation type="relation3">
<entityType5>c</entityType3>
<entityType6>10</entityType4>
<entityType6>11</entityType4>
<entityType6>12</entityType4>
</relation>
</root>
I need to transform via XSLT to a HTML table that contains:
<table>
<tr class="odd"><td>
a --> 1
</td></tr>
<tr><td>
a --> 2
</td></tr>
<tr class="odd"><td>
a --> 3
</td></tr>
<tr><td>
b --> 7
</td></tr>
<tr class="odd"><td>
b --> 8
</td></tr>
<tr><td>
b --> 9
</td></tr>
<tr class="odd"><td>
c --> 10
</td></tr>
<tr><td>
c --> 11
</td></tr>
<tr class="odd"><td>
c --> 12
</td></tr>
</table>
Please note the odd/even alternations of the table’s rows. I need to encode those as well via XSLT. Possible?
The basic question is actually how can I keep an index variable to indicate if the current row is odd or even while parsing this structure.
This would be enough to solve this because I currently have a … for the 2 relation types and then I iterate via a for-each over relation1/entityType2 and another for for-each over relation2/entityType4.
Thank you!
UPDATE-1:
Please note that the resulting table iterates through both relation1 and relation2 XML elements and it must somehow keep a global index that runs among both type of relations to correctly set the odd/even class when finishing the relation1 iteration and passing to relation2.
UPDATE-2:
Currently I have a code similar to this but I don’t know how to easily refactor it to handle the class=”odd” setting on tr. The templates Display_Relation currently display the text for relations.
<xsl:template match="relation">
<xsl:choose>
<xsl:when test="contains(@xsi:type, 'relation1')">
<xsl:for-each select="entityType2">
<tr><td>
<xsl:call-template name="Display_Relation1">
<xsl:with-param name="source" select="../entityType1/text()"/>
<xsl:with-param name="destination" select="./text()"/>
</xsl:call-template>
</td></tr>
</xsl:for-each>
</xsl:when>
<xsl:when test="contains(@xsi:type, 'relation2')">
<xsl:for-each select="entityType4">
<tr><td>
<xsl:call-template name="Display_Relation2">
<xsl:with-param name="source" select="../entityType3/text()"/>
<xsl:with-param name="destination" select="./text()"/>
</xsl:call-template>
</td></tr>
</xsl:for-each>
</xsl:when>
<xsl:when test="contains(@xsi:type, 'relation3')">
<xsl:for-each select="entityType6">
<tr><td>
<xsl:call-template name="Display_Relation3">
<xsl:with-param name="source" select="../entityType5/text()"/>
<xsl:with-param name="destination" select="./text()"/>
</xsl:call-template>
</td></tr>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:template>
Try something like this…
This assumes that the current context is
*[parent::relation](entityType1, entityType2, etc.), however the key piece is the use of thepreceding::axis.If you wanted, you could also use something like
preceding::*[starts-with(name(),'entityType')]instead ofpreceding::*[parent::relation].