Pages :
Existe t-il un moyen de mettre dans une feuille XSLT un lien vers une feuille XML ? Je sais faire l'inverse (faire un lien dans un XML vers une XSLT), mais je ne trouve nulle part ou il est expliqué comment mettre le lien dans la page XSLT.
Modifié par mathmax (21 Mar 2006 - 12:08)
Bonjour,

Pour faire référence dans un fichier XSLT à un fichier XML il faut utiliser la fonction document().
Je ne trouve nulle part comment faire avec la fonction document().
Pourrais-tu m'indiquer comment tu l'utilises ? (un exemple)
Ok j'avais vu ces liens. C'est exactement les recherches que j'avais faite (à ceci près que sur google j'avais recherché en français).
Je ne pensais pas que l'on pouvait l'écrire dans une balise <xsl:for-each par exemple. Je m'attendais à un lien global... Enfin bon j'ai finalement écris :

<xsl:for-each select="document('favoris.xml')//favoris/favori">
  <p><strong><xsl:value-of select="fr/produit"/></strong><br /><xsl:value-of select="image"/></p>
</xsl:for-each>

puisque j'ai un doc xml dans le même dossier qui s'appelle favoris.xml

et qui possède une hierrarchie comme celà :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<favoris xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<favori></favori>
         <favori></favori>
	<favori></favori>
         <favori></favori>
</favoris>


mais ça ne marche pas quand j'éxécute le fichier xslt avec IE6.
Modifié par mathmax (13 Feb 2006 - 00:05)
personne ne sait me dire pourquoi mon lien vers ma feuille XML (dans la balise <xsl:for-each > de mon doc XSLT) ne marche pas ?
Peut-être tout simplement parce que le moteur de transformation MSXML ne supporte pas cette fonction...

Testes-tu en local, ou bien ton fichier à transformer est-il sur un serveur?
Non je teste ça en local. J'ai juste mis ce lien et je comptait sur le navigateur pour faire la transformation (je sais que IE 6 peut faire les transformations côté client).
Gilles à raison, je crois que ni FF ni IE ne connaissent la fonction document().

Si tu tiens absoluement à réaliser cette transformation sur le poste client avec appel à du contenu tiers il ne reste plus qu'a te lancer avec Ajax.
Non je n'y tiens pas absolument. Je ferais ma transformation côté serveur. Dans ce cas, ce lien marchera sans problème non ?
Bonjour,

Je pense que l'erreur est dans l'expression xpath, il faut écrire :
<xsl:for-each select="document('favoris.xml')/favoris/favori">

(1 seul /)

au lieu de :
<xsl:for-each select="document('favoris.xml')//favoris/favori">


Il peut également y avoir un problème de chemin, personnellement je préfère utilsé des chemin absolue pour être sûr que ça marche quelque soit l'endroit où je stock mes xml et xsl. Dans le cas d'un chemin relatif, il faut garder à l'esprit que la référence est le fichier xml sur lequel s'applique la xsl et non le fichier xsl lui même.

Il me semble par ailleurs que la fonction document() fonctionne en client sur IE.

cdlmt

matt
oui ça marche en effet. Par contre ça ne marche plus dès que j'insère mon fragment XSLT dans une page dynamique. La fonction document() ne semble plus marcher que je mette mon chemin en absolu ou en relatif. Une idée du problème ?
Difficile de savoir...
J'ai vérifié sous IE6, la fonction document() fonctionne très bien
en effectuant la transformation avec javascript sur le client (load(xml), load(xsl) et document.write(xml.transformNode(xsl)) grosso modo) ainsi que si on met directment la feuille xsl dans le xml (<?xml-stylesheet type="text/xsl" href="xsl.xsl"?>)

Mais je viens de me rendre compte que dans le code que tu as donnée, même si la fonction marche elle n'affiche rien compte tenu de ce que tu as dans le for-each et le contenu du fichier favoris.xml

A partir du moment ou tu es dans le
<xsl:for-each select="document('favoris.xml')/favoris/favori"> 

le noeud context devient le noeud favoris, et <xsl:value-of select="fr/produit"/> est vide car le neoud <favori> n'a pas de fils <fr> d'après ce que tu as décris dans favoris.xml...


en fait je pense que ta fonction document() marche dans :

<xsl:for-each select="document('favoris.xml')/favoris/favori">
  <p>
      <strong><xsl:value-of select="fr/produit"/></strong><br/>
      <xsl:value-of select="image"/>
  </p>
</xsl:for-each>


mais elle génère :

  <p>
      <strong></strong><br/>
  </p>


autant de fois qu'il y a de neoud favori dans favoris.xml,
ce qui dans ton navigateur n'affiche rien exepté des sauts de ligne...

Je me trompe peut être ?
test :

<xsl:for-each select="document('favoris.xml')/favoris/favori">
     Hello<br/>
</xsl:for-each>


Si tu as plusieus hello à l'affichage c'est que la fonction marche.
Modifié par mattmatt (06 Mar 2006 - 10:14)
Administrateur
Bonjour,

merci de rajouter les balises [ code] ... [ /code] STP. Ce n'est point lisible là Smiley cligne

Felipe
a écrit :
le noeud context devient le noeud favoris, et <xsl:value-of select="fr/produit"/> est vide car le neoud <favori> n'a pas de fils <fr> d'après ce que tu as décris dans favoris.xml...


Je crois que tu te trompes car <fr> est bien un noeud fils du noeud <favori> et le chemin que j'ai donné me semble correct. Je n'ai d'ailleurs aucun "Hallo" à l'affichage quand j'éxécute ma page dynamique dans laquelle j'ai fais appel à un fragment XSL.

Mais, si tu veux bien, parlons plutôt d'un exemple très simple que je viens de faire afin de bien cibler le problème.

J'ai crée dans un même dossier :
- 2 pages XML noms.xml et commentaires.xml qui ont réspectivement les structures suivantes :

<Root>
	<Item>
		<Nom>Nom1</Nom>	
	</Item>
	<Item>
		<Nom>Nom2</Nom>	
	</Item>
...
</Root>


et

<Root>
	<Item>
		<Commentaire>commentaire1</Commentaire>	
	</Item>
	<Item>
		<Commentaire>commentaire2</Commentaire>	
	</Item>
...
</Root>


- 1 feuille XSL test.xsl. Entre les balises template, j'ai mis :

<p><xsl:value-of select="Root/Item/Nom"/></p>
<p><xsl:value-of select="document('http://www.orkos.com/tests/commentaires.xml')//Item/Commentaire"/></p>

(donc un appel à Nom (dans noms.xml) directement et un appel à commentaire (dans commentaires.xml) par le biais de la fonction document()).

- 1 page dynamique test.aspx dans laquelle je fais appel à mes document noms.xml et test.xsl et que je transforme grâce au fichier MM_XSLTransform.vb. Voilà à quoi ressemblent ces appels :

<body><%
Dim mm_xsl As MM.XSLTransform = new MM.XSLTransform()
mm_xsl.setXML(Server.MapPath("noms.xml"))
mm_xsl.setXSL(Server.MapPath("test.xsl"))
Response.write(mm_xsl.Transform())
%></body>


Maintenant je fais les tests suivants :

Dans mon fichier noms.xml, j'ai ajouté un lien vers la feuille test.xsl.
Quand j'appelle noms.xml dans le navigateur, l'obtiens ceci.
Le nom s'affiche correctement. Dans la feuille XSL, la fonction document() est également correctement intérprétée car mon commentaire s'affiche bien en dessous du nom. Jusqu'ici tout fonctionne donc nomralemement.

Maintenant j'éxécute la page test.aspx qui je le rapelle fais appel à noms.xml et test.xsl. J'obtiens ceci. Ici le commentaire ne s'affiche pas. La fonction document() ne semble pas être interprétée. Le chemin Xpath

document('http://www.orkos.com/tests/commentaires.xml')//Item/Commentaire 


est pourtant correct puisque le commentaire s'affichait lors de l'éxécution directe de noms.xml.

Et c'est là que je ne comprends pas pourquoi dans le deuxième cas, ma fonction document() n'est pas intérprétée... Une explication ?

Je mets ici un zip contenant tout l'exemple (y compris le doc vb de transformation), c'est peut-être plus clair d'étudier ça en local.

Merci d'avance pour votre aide.
Salut,


Je m'étais fourvoyé dans une autre explication car dans l'exemple que tu avais donné <favori> n'avais pas de fils <fr>. Le problème semble être en effet du côté de l'appel de document().
chapo pour l'effort d'expression de ton problème en tout cas, c'est très clair.

Je n'ai pas trop le temps maintenant de regarder le zip.
Mais peut-être juste un suggestion :
Quand tu effectues la transformation en aspx, celle ci se fait au niveau du serveur et tu lui demande d'aller chercher un document sur le net qui est stocké ... sur ce serveur justement !

en fait je pense que dans le cas de la transformation coté serveur, il ne faut pas donner une url en argument de document()
document('http://www.orkos.com/tests/commentaires.xml')//Item/Commentaire 

mais le chemin physique du document sur le serveur, qqchose comme ça :
document('c:\inetpub\tonSite\commentaires.xml')//Item/Commentaire


petite astuce au passage : tu peux stocker le repertoire de base de ton site c:\etc dans un un fichier unique fichier constantes.xsl sous une variable
<xsl:variable name="rootSite" select="'c:\etc'"/>

et l'appeler depuis toutes tes xsl en faisant
<xsl:import href="../constantes.xsl"/> 
(chemin relatif ici).
Comme ça si tu change de serveur, tu n'as qu'a changer la valeur de cette variable et non tous tes appels document()...

Sinon, dans le cas où tout est dans le même répertoire tu peux aussi utiliser les chemins relatifs en ne faisant que :
document('commentaires.xml')//Item/Commentaire

(à vérifier)

en esperant que ce soit ça Smiley cligne

PS: tiens au fait ça marche avec les "//" ?
Désolé mais ça ne marche ni avec une URL du type : c:\inetpub\tonSite\commentaires.xml ni avec une URL relative. En fait ça marche si on visualise en éxécutant le fichier noms.xml, mais pas si on éxécute la page test.aspx. Toujours le même problème...
je viens de tester avec ton fichier zip.
je ne suis pas à la page avec aspx (pour l'instant j'utilise asp avant de me mettre à php...), donc j'ai réécrit le transformation en asp (je te l'a mets plus bas si ça peut aider ?).

avec
document('http://www.orkos.com/tests/commentaires.xml')


j'ai l'erreur suivante :

a écrit :
Erreur lors de l'analyse de « http://www.orkos.com/tests/commentaires.xml ». Aucune donnée n'est disponible pour la ressource spécifiée.


pourtant le fichier est bien accessible quand je tape l'adresse dans mon navigateur.

avec :
document('commentaires.xml')
ou
document('C:\testPourDocument\commentaires.xml')


ça marche très bien, j'obtiens bien :
<p>Nom1</p>
<p>commentaire1</p>


Mais apparement ça ne marche pas non plus chez toi avec ces url... Smiley decu

Dernière piste avant que je ne sêche, sais tu quel parser xml est utilisé sur le serveur ? reconnais-il bien la fonction document() ?
en effet selon que tu fais la tranformation xml/xsl sur le client (par javascript ou avec un lien vers la xsl dans le xml) ou sur le serveur, ce n'est pas le même parser qui est utilisé, ça expliquerait pourquoi la même tranformation fontionne d'un côté mais pas de l'autre.... enfin je dis ça c'est vraiment à court d'idée...

J'espère que tu vas trouvé, bon courage !


PS : le code de transformation asp que j'ai utilisé :
	Dim objXML, objXSL
	set objXML= Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
		objXML.async = false
		objXML.load Server.MapPath("noms.xml")
	set objXSL= Server.CreateObject("Msxml2.XSLTemplate")
		objXSL.async = false
		objXSL.load Server.MapPath("test.xsl")
	
	Response.write objXML.transformNode(objXSL)
	
	Set objXML=Nothing
	Set objXSL=Nothing
Pages :