I'm learning to use XSL to parse XML into HTML/XHTML.
The XLST <xsl:for-each>
element is a core element of the language that allows looping. However posts here and elsewhere suggest using this is common for beginners (which I am!) and is poor style.
My question is: what are better (as in more efficient / elegant / better style) options to <xsl:for-each>
loops and why?
In the example below I used nested <xsl:for-each>
and <xsl:choose>
elements to loop through the required nodes with a conditional <xsl:when>
test. This works okay and selects the nodes I need, but does feel rather clunky...
Your wisdom and insights would be greatly appreciated!
My example XML is a report generated by a Stanford HIVdb database query: https://hivdb.stanford.edu/hivdb/by-sequences/
XSD schema is here: https://hivdb.stanford.edu/DR/schema/sierra.xsd
My example XML report is here: https://github.com/delfair/xml_examples/blob/main/Resistance_1636677016671.xml
My example XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>Example Report</title>
</head>
<body>
<h3>Significant mutations</h3>
<xsl:for-each select=".//geneData">
<xsl:choose>
<xsl:when test="gene='HIV1PR'">
Protease inhibitor mutations<br/><br/>
</xsl:when>
<xsl:when test="gene='HIV1RT'">
Reverse transcriptase inhibitor mutations<br/><br/>
</xsl:when>
<xsl:when test="gene='HIV1IN'">
Integrase inhibitor mutations<br/><br/>
</xsl:when>
</xsl:choose>
<table>
<xsl:for-each select=".//mutation">
<xsl:choose>
<xsl:when test="classification='PI_MAJOR' or classification='PI_MINOR' or classification='NRTI' or classification='NNRTI' or classification='INI_MAJOR' or classification='INI_MINOR'">
<tr>
<td>Class</td>
<td>Mutation</td>
</tr>
<tr>
<td><xsl:value-of select="classification"/></td>
<td><xsl:value-of select="mutationString"/></td>
</tr>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</table><br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Resulting HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Example Report</title>
</head>
<body>
<h3>Significant mutations</h3>
Protease inhibitor mutations<br><br><table></table>
<br>
Reverse transcriptase inhibitor mutations<br><br><table>
<tr>
<td>Class</td>
<td>Mutation</td>
</tr>
<tr>
<td>NNRTI</td>
<td>K103N</td>
</tr>
</table>
<br>
Integrase inhibitor mutations<br><br><table></table>
<br>
</body>
</html>