Así es como lo haría, utilizando el método Muenchean. Google 'xslt muenchean' para obtener más información de personas más inteligentes. Puede haber una manera inteligente, pero se lo dejo a los demás.
Una nota, evito el uso de mayúsculas al comienzo de los nombres de elementos xml, por ejemplo, 'Archivo', pero eso depende de usted.
<?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>
La idea es, clave cada elemento del archivo usando su valor de texto. Luego, solo muestre los valores del archivo si son el mismo elemento que el que tiene la clave. Para verificar si son iguales, use generate-id. Hay un enfoque similar donde se compara el primer elemento que coincide. No puedo decirte cuál es más eficiente.
He probado el código aquí usando Marrowsoft Xselerator, mi herramienta xslt favorita, aunque ya no está disponible, afaik. El resultado que obtuve es:
<html>
<body>
<h1>file1</h1>
<p>desc1</p>
<p>desc2</p>
<h1>file2</h1>
<p>desc1</p>
</body>
</html>
Esto está usando msxml4.
He ordenado la salida por Archivo. No estoy seguro si quieres eso.
Espero que esto ayude.
Perfecto, gracias! Y aplausos para la punta muencheana ... – rjohnston
Saludos. Ni siquiera me di cuenta de que eres un australiano, de lo contrario habría utilizado muchos más coloquialismos. :) –
@rjonston: He proporcionado una solución un poco más limpia y probablemente un poco más eficiente que Richards. –