I would like to write some generic templates to transform collections of nodes into HTML lists. Each element of the collection should correspond to one list item. Ideally I would write
<xsl:apply-templates select="..." mode="ul"/>
along with a template which matches the individual elements in the selection, and the resulting HTML should look like
<ul>
<li>Transformation of first element in selection</li>
<li>Transformation of second element</li>
...
</ul>
That is, the content of each <li>
is generated by a non-generic template; but the list structure itself is generated by a generic one. The problem is to write a generic template that produces this list structure for any non-empty collection, and no output for an empty collection.
I tried the following:
<xsl:template match="*" mode="ul">
<xsl:if test="count(*) > 0">
<ul>
<xsl:apply-templates select="*" mode="li"/>
</ul>
</xsl:if>
</xsl:template>
<xsl:template match="*" mode="li">
<li>
<xsl:apply-templates select="." />
</li>
</xsl:template>
But this doesn't work: each element of the collection will individually become a <ul>
. Conceptually, what I want is a way to transform the collection itself into a <ul>
, and then turn the elements of the collection into individual <li>
s.
Important here:
The test for the non-empty collection should be in the generic template, because I don't want to wrap every call to this template with a conditional, and I don't want to output empty
<ul>
elements when the collection is empty.In the XML documents I'm transforming, there is in general no common parent of the elements in the collection. That means I cannot transform the parent into the
<ul>
and its children into<li>
s; there is no element in the source document which corresponds to the<ul>
.
Is this possible? The searching I've done increasingly suggests to me that it isn't, but that seems insane to me, since this must an incredibly common use case.