DOM et XSLT : problème hardu

DOM et XSLT : problème hardu - PHP - Programmation

Marsh Posté le 18-05-2005 à 23:41:14    

Bonjour, je bosse en PHP 5.
 
mon but est d'appliquer une transformation XSL (lue à partir d'un fichier puis un peu modifiée) à un DOMDocument XML.
 

Code :
  1. // Chargement du document XML
  2. $xml = new DOMDocument;
  3. $xml->load('document.xml');
  4. // Chargement de la transformation originale (transfo1)
  5. $xsl = new DOMDocument;
  6. $xsl->load('transfo1.xsl');
  7. // Transformation !
  8. $proc = new XSLTProcessor;
  9. $proc->importStyleSheet($xsl);
  10. echo $proc->transformToXML($xml);


 
Jusque là ça marche, pas de soucis...
 
Mon problème est que je veux rajouter une deuxième transformation au document, qui provient d'un fichier différent, en fonction d'une variable PHP.
Si $deuxieme_xsl = 'transfoA.xsl' , il faudra rajouter la transformation transfoA en plus de transfo1.
Si $deuxieme_xsl = 'transfoB.xsl' , il faudra rajouter la transformation transfoB en plus de transfo1.
etc...

Apparemment XSLTProcessor ne peut charger qu'une feuille de style, on doit donc passer par une importation dans la première feuille de style. Il faut donc rajouter ça à transfo1 :
 

Code :
  1. <xsl:import href="transfoA.xsl"/>


 
(avec transfoA pour exemple, mais ce nom de fichier est variable).
 
Je rapelle que c'est une directive top-level qui doit être directement à la suite de

Code :
  1. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">


 
1ère tentative : faire un appel PHP dans la feuille de style transfo1.xsl
 

Code :
  1. <xsl:import href="<xsl:value-of select="php:function('deuxieme_xsl')"/>"/>


 
Evidemment il est interdit d'imbriquer deux directives de la sorte.. :sweat: Donc ça ne marche pas.
 
2ème tentative : modifier le DOM de transfo1.xsl
 
Sachant que la première balise est xsl: output , je fais en sorte de rajouter xsl:import juste avant :
 

Code :
  1. // nouvel élément xsl:import
  2. $import = $xsl->createElement('xsl:import');
  3. // on repère l'élément xsl:output (j'ai vérifié, il ne faut pas mettre le "xsl:" devant dans getElementsByTagName)
  4. $output = $xsl->getElementsByTagName('output')->item(0);
  5. // on insère xsl:import juste avant
  6. $import = $xsl->documentElement->insertBefore($import, $output);
  7. // on rajoute l'attribut href qui pointe vers la secodne transformation variable
  8. $import->setAttribute('href', $deuxieme_xsl);


 
A première vue le résultat paraît parfait, voici l'affichage string du DOMDocument $xsl de transfo1 ainsi modifié :
 

Code :
  1. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  2.   <xsl:import href="transfo2.xsl"/><xsl:output etc...


 
Malheureusement, une erreur se produit ensuite sur XSLTProcessor::importStyleSheet :
 

Code :
  1. Warning: Found a top-level element xsl:import with null namespace URI


 
3ème tentative : pareil, en jouant avec les namespaces
 
Voici le nouveau code PHP :
 

Code :
  1. // nouvel élément xsl:import
  2. $import = $xsl->createElementNS('xsl', 'import');
  3. // on repère l'élément xsl:output
  4. $output = $xsl->getElementsByTagName('output')->item(0);
  5. // on insère xsl:import juste avant
  6. $import = $xsl->documentElement->insertBefore($import, $output);
  7. // on rajoute l'attribut href qui pointe vers la secodne transformation variable
  8. $import->setAttribute('href', $deuxieme_xsl);


 
Voici l'affichage string du DOMDocument $xsl de transfo1 ainsi modifié :
 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 
  <import xmlns="xsl" href="transfo2.xsl"/><xsl:output etc...


 
le xsl:import n'a pas la forme escomptée, mais XSLTProcessor::importStyleSheet ne génère plus d'erreur.
En revanche, la deuxième transformation n'est pas effectuée :( Le XSLTProcessor ignore l'importation ...
 
 
Voilà, je suis à bout de souffle, j'en fais appel à vous ! Merci d'avance :jap:


Message édité par Chase le 18-05-2005 à 23:46:06
Reply

Marsh Posté le 18-05-2005 à 23:41:14   

Reply

Marsh Posté le 19-05-2005 à 08:36:12    

Pfiouuuu, un superbe post très long et pas une réponse... Ne te décourage pas, je suis sûr qu'une âme charitable voudra bien t'aider.
En ce qui me concerne, je n'ai absolument rien compris ;-)
(Et puis ça joue le rôle d'un 'up bien caché ;-)

Reply

Marsh Posté le 19-05-2005 à 14:35:01    

je ne peux pas t'aider mais aidez le , pour une fois qu'un post ressemble a qqchose avec un mec qui s'est bien démené et qui a essayé ...

Reply

Marsh Posté le 19-05-2005 à 19:23:52    

Merci pour votre soutien :D

Reply

Marsh Posté le 19-05-2005 à 20:43:10    

Tu as essayé de faire 2 transformations de suite? C'est p-e pas tres elegant mais ... si pas de meilleure soluce..


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 19-05-2005 à 20:47:57    

Je crois bien que tout ce qui n'est pas transformé la première fois, est perdu :(

Reply

Marsh Posté le 20-05-2005 à 09:35:30    

As-tu essaye d'utiliser ta premiere methode mais en passant par une variable ?
Bon si import et toplevel, je sais pas si tu peux metre une var avant...
Faudrait que tu essaye.
 
Gerne :

Code :
  1. <xsl:variable name="import" select="php:function('deuxieme_xsl')"/>
  2. <xsl:import href="{$import}"/>


 
J'ai jamais utilise de fonctions php a l'interieur d'un xsl, donc j'ai simplement tente d'adapter ton code, je sais pas s'il est correct.


Message édité par cerel le 20-05-2005 à 09:35:43
Reply

Marsh Posté le 20-05-2005 à 13:40:48    

Bon ca répond pas à la question de savoir d'où vient le fait que tes essais ne marchent pas mais sinon, il y a toujours la solution de faire 2 xsl, l'un avec la directive import et l'autre sans.
 
Après, tu appelles le bon en fonction de ta variable PHP.
 
Sinon, tu as essayé de sortir le résultat en plat et d'utiliser un autre parser genre ant ? Le fait que n'ait pas d'erreur de parsing sur ta dernière tentative inciterait à penser que l'xsl généré est correct et que tu as peut-être un soucis dans des xls/xml.

Reply

Marsh Posté le 20-05-2005 à 22:43:07    

Merci Cerel, j'y ai cru mais :
 

Warning: compilation error: file transfo1.xsl element import
Warning: xsltParseStylesheetTop: ignoring misplaced import element


 
On dirait bien qu'on ne peut pas mettre de variable avant un top-level :sweat:

Reply

Marsh Posté le 21-05-2005 à 01:19:20    

Euhhh, au fait, je viens de remarquer un truc sur http://www.w3schools.com/xsl/el_import.asp

Citation :

Note: An imported style sheet has lower precedence than the importing style sheet.

C'est peut-etre ca ton probleme, non ?
 
En revanche tu peux essayer xsl:include

Citation :

Note: An included style sheet has the same precedence as the including style sheet.


Message édité par cerel le 21-05-2005 à 01:23:00
Reply

Marsh Posté le 21-05-2005 à 01:19:20   

Reply

Marsh Posté le 21-05-2005 à 12:16:24    

Code :
  1. <xsl:variable name="feuille" select="php:function('deuxieme_xsl')"/>
  2. <xsl:include href="{$feuille}"/>


 

Warning: xsl:include : invalid URI reference {$feuille}


 
Y'a plus le problème du top-level mais on dirait que la variable xsl n'est pas interprétée :(
 
Dis, Cerel, tu utilises les includes pour centraliser du code (comme les balises méta par exemple), ou bien tu les réécris sur chaque xsl ?


Message édité par Chase le 21-05-2005 à 12:16:56
Reply

Sujets relatifs:

Leave a Replay

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