an alternative method which avoids using the expensive preceding-sibling and following-sibling expressions is to use keys for your grouping (this method is known as the Muenchian method).
Create a key based on the whats_new_id attribute by placing this line at the top of your stylesheet
Code:
<xsl:key name="NewArticles" match="metadata" use="@whats_new_id"/>
Then you can use this key to group the articles and select all articles within a group by changing your whats_new_article template to the following (I've commented out your for-each lines which I've changed to use the keys). Note that I've also changed the expensive \\ path expression to use the actual path, since we know exactly what it is.
Code:
<xsl:template name="whats_new_article">
<xsl:for-each select="root/metadata_object/metadata[generate-id()=generate-id(key('NewArticles', @whats_new_id)[1])]">
<xsl:sort select="@whats_new_id"/>
<table cellpadding="0" cellspacing="0" align="center" border="0" bgcolor="#ffffff" width="100%">
<tr class="mdo">
<td colspan="2">
<xsl:for-each select="metadata_detail[@mdi_type_cd='URL']">
<xsl:value-of select="@mdi_efctv_dt_month"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@mdi_efctv_dt_year"/>
</xsl:for-each>
<br/>
</td>
</tr>
<tr>
<td width="25"> </td>
<td class="new">
<xsl:for-each select="key('NewArticles', @whats_new_id)">
<xsl:sort select="@mdi_effctv_dt"/>
<li>
<a target="_self">
<xsl:attribute name="href"><xsl:for-each select="metadata_detail[@mdi_type_cd='URL']"><xsl:value-of select="@mdi_txt"/></xsl:for-each></xsl:attribute>
<xsl:value-of select="@mdo_nm"/>
</a>
</li>
</xsl:for-each>
</td>
</tr>
</table>
</xsl:for-each>
</xsl:template>
rgds
Phil