GeckoGeek.fr

Paradigme d'un lézard

Jeudi 19 Octobre 2017

Ajouter des variables sous Ajaxslt via ExprContext

Par Vinz le 23/11/2009 dans Programmation | 2 commentaires

Récemment nous avons vu comment faire le lien entre un fichier XML et un fichier XLST en Javascript. Mais souvent il est question d’envoyer des paramètres qui seront utilisés dans le XSLT. Malheureusement la documentation d’Ajaxslt (ou même de l’implémentation jQuery, cela revient au même) n’est pas très explicite sur cet aspect. Voyons donc en quelques lignes comment s’en occuper !
Ajaxslt / jQuery

Rappels

Voici un petit rappel de code sur l’utilisation simple de ces librairies, sans passer de paramètre.

// Parsing de vos codes xml et xslt
var xml = xmlParse(XML_CODE);
var xslt = xmlParse(el(XSLT_CODE);
// On procède !
var html = xsltProcess(xml, xslt);
// On insère le résultat dans la div
document.getElementById("output").innerHTML = html;

Ici nous utilisons la commande xsltProcess pour combiner le XML et le XSLT. Toutefois pour passer des paramètres nous allons devoir faire autrement.

Etape par étape

La variable à faire transiter

Imaginons que vous souhaitiez indiquer un ID à votre XLST afin qu’il sélectionne une fiche selon ce dernier. Dans notre exemple nous l’aurons sous cette forme :

var articleID = 3;

Ajouter une variable

Avant de pouvoir passer un paramètre nous devons localiser le XML dans un contexte. Puis nous lui ajoutons les paramètres et procédons après de façon similaire à notre dernier billet.

// Parsing de vos codes xml et xslt
var xml = xmlParse(XML_CODE);
var xslt = xmlParse(el(XSLT_CODE);
// Init Contexte xml
var myContext = new ExprContext(xml);
// Add Variable
myContext.setVariable("articleID", new StringValue(articleID));
// Out the process
xsltProcessContext(myContext, xslt, document.getElementById("output"));

Si on regarde de plus près. D’abord on parse les codes XML et XSLT. Puis on créé le contexte XML, et on ajoute la variable articleID (notez qu’il faut la convertir avec un StringValue() ou autre fonction du même type). Et enfin on procède à la combinaison avec xsltProcessContext. Le dernier paramètre de cette méthode est l’objet qui contiendra le résultat. Utilisez quelque chose de classique comme getElementById car passer par jQuery (avec $(“”)) semble buguer.

Récupérer le code XML / XSLT depuis un fichier

En principe vous aurez vos codes dans des fichiers. Dans ce cas je vous conseille de passer complètement par jQuery et le plugin Ajaxslt correspondant. Pour récupérer le code vous pouvez passer par une requête Ajax toute simple :

$.ajax({
	async: false,		// On ne fait pas de requête asynchrone pour éviter un problème
	type: "POST",
	url: "fichier.xml",	// Url de votre fichier
	dataType: "html",	// Type de contenu que vous souhaitez recevoir
	success: function(msg){
		var xml = xmlParse(msg);
	}
});

Toutefois attention, ici votre variable xml est locale dans la fonction success. Il est donc conseillé de mettre le contenu dans une variable globale de classe (cf le code tout à la fin). Mais si vous souhaitez procéder d’une autre façon, faites vous plaisir :-] (Vous pouvez effectuer la même chose pour le fichier xslt !)

Sinon pour le coup de la requête asynchrone, si vous le faite en parallèle alors il y a un risque que vous tentiez de faire le xsltProcess et le reste avant que les fichiers soient chargés. Cela mènerait bien évidemment à un méchant bug Javascript ! Il est bien sur possible de procéder autrement pour éviter un léger freeze du navigateur.

Lire la variable dans le fichier XLST

Rapide rappel sur comment lire la variable dans votre fichier XLST. D’abord vous devez indiquer que cette variable sera (peut-être) déclarée :

<xsl:param name="articleID"/>

Ensuite il vous suffit de faire référence à cette variable avec un $ dans la suite de votre code. Par exemple si vous souhaitez vérifier si la variable existe, faites ainsi :

<xsl:when test="$articleID"> 
	<xsl:apply-templates select="/path-to-articles/article[@id=$articleID]"/> 
</xsl:when>

Exemple sous forme de classe

Si vous souhaitez un code complet reprenant un peu tout ce dont nous venons de parler, en voici un exemple. Attention, pensez à bien inclure la librairie jQuery et la librairie Ajaxslt (ou son extension jQuery). Ici je ne mets que le code s’occupant de traiter le tout.

/*
 * Subject: Exemple Ajaxslt / Ajout d'une variable
 * Site Web: GeckoGeek.fr
 * Author: Vinz
 */
var xsltReader = {

	xml: null,
	xslt: null,

	init: function() {

		// Get the xml files content
		$.ajax({
			async: false,
			type: "POST",
			url: "article.xml",
			dataType: "html",
			success: function(msg){
				xsltReader.xml = xmlParse(msg);
			}
		});

		$.ajax({
			async: false,
			type: "POST",
			url: "article.xsl",
			dataType: "html",
			success: function(msg){
				xsltReader.xslt = xmlParse(msg);
			}
		});

	},

	loadArticle: function(articleID) {

		// Empty div
		$("#outArticle").empty();
		// Init xml
		var myContext = new ExprContext(xsltReader.xml);
		// Add Variable
		myContext.setVariable("articleID", new StringValue(articleID));
		// Out the process
		xsltProcessContext(myContext, xsltReader.xslt, xsltReader.element("outArticle"));

	},

	element: function(id) {

		return document.getElementById(id);

	},

}

// Quand la page est chargée on init. le script
$(document).ready(function() {

	xsltReader.init();

});

Dans le code ci-dessus nous avons un object xsltReader avec trois fonctions :

  • init() qui charge les fichiers XML et XSLT une fois pour toute
  • loadArticle(); qui charge un article dans la div “outArticle”
  • element() qui retourne l’élèment qui contiendra le code

Et enfin nous avons la méthode “$(document).ready(function()” qui se déclenche quand la page est chargée !
En principe il ne vous reste plus qu’à adapter un peu ce script en fonction de vos besoins et le tout devrait bien marcher :-) Penser à bien indiquer le chemin vers vos fichiers xml et xslt.

Si ce billet vous a été utile ou si vous avez une question, n’hésitez pas à laisser un commentaire si vous avez le temps :-]

Commentaires (2)
  1. Tannax le 24 Nov 2009 à 00:08

    C’est marrant que tu parles de ce sujet, on en à parler récemment au boulot ce qui me permet d’ajouter un petit point à ton article.

    Pour faire simple on à une GROSSE application qui tourne sous IIS coté client (ASP) et TOMCAT coté serveur (JAVA).

    Le parsing xml, template xml ou autres transformations XML sont utilisées pour faire dialoguer les deux parties. C’est à dire que lors d’une requête faite par le client, il va y en avoir 4 (template XML puis parsing XSL, de nouveau parsing XSL après requête en BDD et enfin template XML).

    Le problème dans tout ça (qui n’en n’ai pas forcément un pour un petit site mais qui peut très vite le devenir) est que chaque transformation XML ou XSL crée des écritures sur le disque et donc des threads (au moins 4 ou 6 si ma mémoire est bonne) pour chaque transformation… faites le calcul… ça grimpe vite !

    C’est pour cela qu’il est préférable d’utiliser, au moins du coté serveur, une servlet et des java beans (on reste dans du java coté serveur) pour que ce traitement soit fait en mémoire ! Ainsi vous diviserez par 2 le nombre d’écritures sur disque et augmenterez les performances de votre application !

    Biensur comme je l’ai dis ce problème n’est pas perceptible pour des applications a faible trafic mais attention quand même à y penser…

    Ci mon explication ne vous à pas touchez pensez à la planète: moins de calculs = moins d’électricité = moins de CO² !!!

    A bientôt,
    Tannax

    PS: Vinz, comme d’hab, un travail remarquable!

  2. Vinz le 24 Nov 2009 à 09:22

    Lut :-)
    Pas un secteur que je maitrise bien (Java :-p) mais c’est vrai que j’aurais pu faire un p’tit paragraphe sur l’utilité de ce type de procédé ^^
    Perso. je le vois surtout comme avantageux pour faire une partie des traitements coté client si tu lui fournis assez vite le xml et xslt (ça t’évite de le faire coté serveur en php par exemple, ou Java). Après c’est pas forcément adapté aux gros sites qui ont une bdd & co, surtout si tu parses plusieurs fois pour ce que tu citais, autant faire du json ou du genre (ou des Beans mdr). Mais pour des sites qui font que du xml ça peut avoir son intérêt. Sachant que bon, de nos jours si on creuse un peu y’a surement des techno. concurrentes intéressantes pour du similaire.
    Quoiqu’il en soit, ça bouffe effectivement en lecture écriture et cpu, donc à utiliser avec discernement ^^
    @+ et merci pour le comm. :-)


Laisser un commentaire