[XSL] Conservation d'éléments après transformation

Conservation d'éléments après transformation [XSL] - XML/XSL - Programmation

Marsh Posté le 03-07-2006 à 16:54:51    

Bonjour.
Je suis amené à faire des transformations sur un noeud particulier dans mon arbre XML. Je dois modifier l'ordre de certains éléments du noeud mais conserver les autres. Voici un exemple: le noeud  

Code :
  1. <Homme>
  2.    <Corps>
  3.       <Jambe>Jambe</Jambe>
  4.       <Bassin>Bassin</Bassin>
  5.       <Tronc>Tronc</Tronc>
  6.       <Tete>Tete</Tete>
  7.    </Corps>
  8.    <Ame />
  9. <Homme>


doit se transformer en :

Code :
  1. <Homme>
  2.    <Corps>
  3.       <Tete>Tete</Tete>
  4.       <Tronc>Tronc</Tronc>
  5.       <Bassin>Bassin</Bassin>
  6.       <Jambe>Jambe</Jambe>
  7.    </Corps>
  8.    <Ame />
  9. <Homme>


Voici le script XSL que j'ai écrit

Code :
  1. <xsl:template match="/">
  2.    <xsl:element name = "Homme" >
  3.       <xsl:copy>
  4.          <xsl:apply-templates />
  5.       </xsl:copy>
  6.    </xsl:element>
  7. </xsl:template>
  8. <xsl:template match="//Corps">
  9.    <xsl:element name="Corps">
  10.       <xsl:element name="Jambe">
  11.          <xsl:value-of select="./Jambe"/>
  12.       </xsl:element>
  13.       <xsl:element name="Bassin">
  14.          <xsl:value-of select="./Bassin"/>
  15.       </xsl:element>
  16.       <xsl:element name="Tronc">
  17.          <xsl:value-of select="./Tronc"/>
  18.       </xsl:element>
  19.       <xsl:element name="Tete">
  20.          <xsl:value-of select="./Tete"/>
  21.       </xsl:element>
  22.    </xsl:element>
  23. </xsl:template>


 
L'ordre des éléments du noeud <Homme> est bien changé mais le noeud <Ame> est écrasé. Y'a-t-il une option à spécifier dans le apply-templates pour qu'il ne touche pas aux noeuds n'étant pas la cible d'un template?
 
Merci d'avance.


Message édité par Morbho le 03-07-2006 à 16:55:30
Reply

Marsh Posté le 03-07-2006 à 16:54:51   

Reply

Marsh Posté le 03-07-2006 à 21:37:58    

Il me semble que le premier template qui matche a priorité. Donc si tu ajoutes un
 
<xsl:template match="*"><xsl:copy-of select="." /></xsl:template>
 
après le <xsl:template match="//Corps">... est-ce que ça ne fontionne pas?

Reply

Marsh Posté le 04-07-2006 à 11:41:49    

Ca ne marche pas beaucoup... En fait, ça me recopie mon XML d'origine sans prendre en compte mes templates. Mais un ami m'a donné des indications. En fait le problème, c'est que je n'utilise des règles que pour des noeuds nommés. Il faut des règles génériques pour les autres noeuds. En ajoutant ce code :  

Code :
  1. <xsl:template match="@*">
  2.    <xsl:copy />
  3. </xsl:template>
  4. <xsl:template match="*">
  5.    <xsl:element name="{name()}" >
  6.       <xsl:apply-templates select="* | text() | @*"/>
  7.    </xsl:element>
  8. </xsl:template>


Tu fais une recopie de l'arbre XML avant d'appliquer les règles particulières, ce qui évite les écrasements de données. En tout cas merci quand même de t'être penché sur le sujet!

Reply

Marsh Posté le 04-07-2006 à 18:28:09    

Je ne comprends pas bien ce dernier code, le permier template sert simplement à faire une copie des attributs et le second un deep-copy des noeud (qui pourrait s'écrire <xsl:template match="*"><xsl:copy-of select="." /></xsl:template> ). Je ne vois pas comment il pourrait résoudre ton problème...
 
Mais je me suis planté, l'ordre des template n'influence pas la priorité. Par contre si je lien bien la norme W3C un match avec un nom de noeud est plus prioritaire que *. Donc j'écrirais

Code :
  1. <?xml version="1.0" ?>
  2. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  3. <xsl:template match="//Homme">
  4.  <xsl:copy>
  5.   <xsl:apply-templates />
  6.  </xsl:copy>
  7. </xsl:template>
  8. <xsl:template match="Corps">
  9.  <xsl:copy>
  10.   <xsl:copy-of select="Tete" />
  11.   <xsl:copy-of select="Tronc" />
  12.   <xsl:copy-of select="Bassin" />
  13.   <xsl:copy-of select="Jambe" />
  14.  </xsl:copy>
  15. </xsl:template>
  16. <xsl:template match="*">
  17.  <xsl:copy-of select="." />
  18. </xsl:template>
  19. </xsl:stylesheet>


Ce qui fonctionne avec l'exemple de ton premier post...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed