It should work as you're expecting if you simply change this line:
<xsl:apply-templates select="contact"/>
to this:
<xsl:apply-templates select="."/>
However, I would propose structuring your XSLT more like this:
<xsl:template match="Record">
<xsl:apply-templates
select="contact[generate-id() =
generate-id(key('contactsbysurname',@surname)[1])]"
mode="group" />
</xsl:template>
<xsl:template match="contact" mode="group">
<xsl:apply-templates select="key('contactsbysurname',@surname)" />
</xsl:template>
<xsl:template match="contact">
<fo:table-row font-size="6.5pt">
<fo:table-cell>
<fo:block text-align="center">
<xsl:value-of select="@title" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="center">
<xsl:value-of select="@surname" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="center">
...
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
Edit
If you just want to show one row of information for each contact, then there's no need to have two nestes for-each
es or two layers of contact
templates. In that case, it's even simpler:
<xsl:template match="Record">
<xsl:apply-templates
select="contact[generate-id() =
generate-id(key('contactsbysurname',@surname)[1])]" />
</xsl:template>
<xsl:template match="contact">
<fo:table-row font-size="6.5pt">
<fo:table-cell>
<fo:block text-align="center">
<xsl:value-of select="@title" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="center">
<xsl:value-of select="@surname" />
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block text-align="center">
...
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>