Aqui está como eu faria isso, usando o método Muenchean. Google 'muenchean XSLT' para mais informações de pessoas mais inteligentes. Pode haver uma maneira inteligente, mas vou deixar isso para os outros.
Uma nota, I evitar o uso de capitais no início de nomes de elementos XML, por exemplo, 'File', mas isso é até você.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:key name="files" match="/Problems/Problem/File" use="./text()"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="Problems"/>
</body>
</html>
</xsl:template>
<xsl:template match="Problems">
<xsl:for-each select="Problem/File[generate-id(.) = generate-id(key('files', .))]">
<xsl:sort select="."/>
<h1>
<xsl:value-of select="."/>
</h1>
<xsl:apply-templates select="../../Problem[File=current()/text()]"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="Problem">
<p>
<xsl:value-of select="Description/text()"/>
</p>
</xsl:template>
</xsl:stylesheet>
A ideia é, chave cada elemento do arquivo usando seu valor de texto. Em seguida, exibir apenas os valores de arquivo se eles são o mesmo elemento como a chave. Para verificar se eles são o mesmo, use gerar-id. Há uma abordagem semelhante, onde você comparar o primeiro elemento que corresponda. Eu não posso dizer-lhe que é mais eficiente.
Eu testei o código aqui usando Marrowsoft Xselerator, minha ferramenta xslt favorito, embora já não está disponível, afaik. O resultado que eu tenho é:
<html>
<body>
<h1>file1</h1>
<p>desc1</p>
<p>desc2</p>
<h1>file2</h1>
<p>desc1</p>
</body>
</html>
Esta é usando msxml4.
Tenho ordenado a saída de arquivo. Eu não tenho certeza se você queria isso.
Eu espero que isso ajude.