Bonjour à toutes et à tous.

Dans un fichier XML, j'aimerais regrouper les noeuds en fonction d'un attribut (Ici l'attribut @sha1).

Fichier XML de départ:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<database>
  <file sha1="179f40">
    <server host="192.168.0.1" port="4672" bandwidth="300"/>
  </file>
 
  <file sha1="279f40">
    <server host="192.168.0.1" port="1664" bandwidth="300"/>
  </file>
 
  <file sha1="179f40">
    <server host="192.168.0.5" port="1664" bandwidth="300"/>
  </file>
 
  <file sha1="279f40">
    <server host="192.168.0.5" port="4672" bandwidth="300"/>
  </file>
</database>
Fichier XML de sortie souhaité:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<database>
  <file sha1="179f40">
    <server host="192.168.0.1" port="4672" bandwidth="300"/>
    <server host="192.168.0.5" port="1664" bandwidth="300"/>
  </file>
 
  <file sha1="279f40">
    <server host="192.168.0.1" port="1664" bandwidth="300"/>
    <server host="192.168.0.5" port="4672" bandwidth="300"/>
  </file>
</database>

Je me suis inspiré de l'exemple donné dans la FAQ (Comment regrouper les noeuds en fonction de leurs éléments qui se ressemblent) pour faire ma feuille de style XSL.

Fichier XSL :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
<?xml version="1.0" encoding="ISO-8859-1"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" cdata-section-elements="title" />
  <xsl:key name="regrouper" match="file" use="@sha1"/>
 
  <xsl:template match="/">
	<database>
	  <xsl:apply-templates select="database/file[generate-id(.)=generate-id(key('regrouper', @sha1)[1])]"/>
	</database>
  </xsl:template>
 
  <xsl:template match="file">
	<xsl:copy-of select="."/>
	<xsl:apply-templates select="//server[../file=current()]"/> 
  </xsl:template>
 
 
  <xsl:template match="server">
	  <xsl:copy-of select="."/>
  </xsl:template>
 
</xsl:stylesheet>
Voici le résultat:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
<?xml version="1.0" encoding="ISO-8859-1"?>
<database>
  <file sha1="179f40">
    <server host="192.168.0.1" port="4672" bandwidth="300"/>
  </file>
  <file sha1="279f40">
    <server host="192.168.0.1" port="1664" bandwidth="300"/>
  </file>
</database>
J'obtient bien le premier serveur, mais pas le second.
J'imagine que l'un de mes problème ce situe sur la ligne suivante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
<xsl:apply-templates select="//server[../file=current()]"/>
J'ai trouvé un post résolu qui semble traiter du même problème, mais sans parvenir à tous comprendre.

Merci de voter aide