IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

XSL/XSLT/XPATH XML Discussion :

[XSLT] Requête dans une base de données


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut [XSLT] Requête dans une base de données
    Bonjour,

    J'ai un fichier XML en entrée. J'utilise un méchanisme XSLT pour générer un fichier XSL-FO de manière à pouvoir ensuite générer un PDF avec ApacheFOP.

    J'ai besoin d'ajouter une fonctionnalité supplémentaire : au moment de la transformation XSLT, suivant la valeur d'une de mes données, j'aurais besoin d'aller me connecter à une base de données pour aller récupérer juste une valeur.

    Malgré mes recherches sur Internet, je n'arrive pas à voir quel est l'outil standard pour ce genre de chose.

    J'ai fait des essais, infructueux, avec Saxon. Ce qui me déçoit, c'est que je n'arrive pas à savoir ce qui coince...

    problème sur ma sql:connection ?? sur ma sql:query ?? rien aucune info ... la génération se passe sans soulever de problème, mais là où je devrais avoir ma donnée récupérée dans la base, je n'ai rien ...

    Aucune trace dans les logs Apache non plus ...

    Mon bout de code est exactement similaire à ce qui est décrit ici :
    http://ajwelch.blogspot.com/2007/09/...from-xslt.html

    ... autrement dit, rien d'extraordinaire

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="2.0"
    	xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	xmlns:sql="/net.sf.saxon.sql.SQLElementFactory">
     
    	<xsl:output method="xml" encoding="utf-8"/>
    	<xsl:param name="driver" select="'oracle.jdbc.driver.OracleDriver'" as="xs:string"/>
    	<xsl:param name="database" select="'jdbc:oracle:thin:@<SERVER>:<BD>'" as="xs:string"/>
     
    	<xsl:param name="user" select="toto" as="xs:string"/>
    	<xsl:param name="password" select="tutu" as="xs:string"/>
     
     
     
    (...)
    	<xsl:choose>
    		<xsl:when (...)
    		</xsl:when>
    		<xsl:otherwise>
    		<xsl:variable name="connection" as="java:java.sql.Connection" xmlns:java="http://saxon.sf.net/java-type">
    		<sql:connect driver="{$driver}" database="{$database}" user="{$user}" password="{$password}"/>
    			<xsl:fallback>
    				<fo:inline font-weight="bold">SQL extensions are not installed</fo:inline>
    			</xsl:fallback>
    		</xsl:variable>
    	<xsl:variable name="resultNico" as="xs:string">
    	<sql:query connection="$connection" 
    		table="ARTICLE" 
    		column="DESIGNATION"
    		where="NUM_ARTICLE='12527'"/>
    	</xsl:variable>
    	<fo:inline font-weight="bold">Des :<xsl:value-of select="$resultNico"/></fo:inline>
    (...)

  2. #2
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut


    Je doute que tu trouves ton bonheur ici.
    Normalement c'est typiquement le type de chose qu'on doit éviter en XSLT , un peu comme de mettre de la programmation spaghetti à base de goto dans un langage style C++ .
    Dans la logique de création du XSLT, il ne devait pas avoir d'accès externe pendant l'exécution, on pouvait récupérer des données ,voir des objets dans le cas de XSLT 2.0 ou du draft XSLT 1.1 en paramètre avant de lancer le traitement, mais pendant....

    En passant , est ce que tu as regardé les commentaires du blog ?

    D'autres ont l'air d'avoir eu des soucis aussi

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par Erwy Voir le message


    Je doute que tu trouves ton bonheur ici.
    Normalement c'est typiquement le type de chose qu'on doit éviter en XSLT , un peu comme de mettre de la programmation spaghetti à base de goto dans un langage style C++ .
    (...)
    Tout à fait d'accord, cette solution ne me semble pas propre, mais c'est la seule que je vois pour l'instant.


    Citation Envoyé par Erwy Voir le message
    (...)
    Dans la logique de création du XSLT, il ne devait pas avoir d'accès externe pendant l'exécution, on pouvait récupérer des données ,voir des objets dans le cas de XSLT 2.0 ou du draft XSLT 1.1 en paramètre avant de lancer le traitement, mais pendant....
    (...)
    Là tu m'intéresses fortement. Il y a un truc sur la transformation XSLT que j'ai du zapper : pour moi - et j'espère que tu vas me dire le contraire - il est impossible de fournir des paramètres à une transformation XSLT (XSLT = XML + XSL --> un peu de ce qu'on veut)

    Mon problème de base est celui-là :
    2 situations possibles à partir d'un même fichier XML
    1. je fais ma transformation sans toucher aux données du XML
    2. je fais ma transformation avec ce fichier XML de base, mais dans lequel quelques données ont besoin d'être remplacées. Cependant, j'ai toutes les infos avant la transformation XSL pour pouvoir les fournir en paramètres, en quelques sorte. Par contre, je ne vois pas comment faire.

    Citation Envoyé par Erwy Voir le message
    (...)

    En passant , est ce que tu as regardé les commentaires du blog ?

    D'autres ont l'air d'avoir eu des soucis aussi
    Oui... ça a qq chose de réconfortant de voir qu'on est pas le seul à galérer !

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    J'ai pas trop le courage de répondre (je suis malade), mais voila un exemple de passage de paramètres au process de XSL-T : http://xml.developpez.com/sources/?p..._javascript_FF
    C'est faisable dans tous les langages.

  5. #5
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    Quelques infos en complément du message précédent

    je ne connais malheureusement pas tous les processeurs et je n'ai jamais pu utilisé tous les proc donc ce qui suis est valable pour MSXML le parseur microsoft et celui de Mozilla.
    Il faudrait que je consulte la doc de saxon pour en savoir plus sur ce dernier.

    Tous les procs peuvent prendre des strings ou des nombres en paramètre

    Mozilla et msxml (et sans doute d'autre) peuvent des noeuds d'un autre document sélectionné par le DOM tu navigue dans ces noeuds (et dans leur descendant voir ascendant) comme si c'etait un autre document XML

    MSXML peut prendre des objets en paramètre mais avec de grosse limitations en javascript en tout cas.

    L'objet doit être construit , on ne peut passer un objet dom natif.On ne peut utiliser que des méthodes, impossible d'accéder aux propriétes directement.


    Je pense que SAXON, vu qu'il implémente XSLT 2.0 doit permettre une assez grande diversité de type en paramètre mais je n'en suis pas sûr

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Merci Erwy, merci Morbo,

    J'ai trouvé de la doc pour cette histoire de passage de paramètres. Je vais me renseigner un peu plus.

    Par contre, je dois avouer que pour répondre à mon problème initial, la connexion à la BD dans la XSLT lui même serait bien plus intéressant.

    Si je trouve un truc, je le proposerai, histoire de voir ce que les experts en pensent, et pour aider quelqu'un éventuellement.

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Il faudrait un serveur applicatif exposant certaines ressources en xml via des URI. En son temps, j'utilisais cocoon, mais je le trouve trop complexe.
    Ca peut se faire aujourd'hui via les architectures dites "REST", ou via webservice URL friendly.
    Après xsl-t pourrait y accéder via la fonction document("URI").
    L'idée étant d'agréger toutes les données nécessaires à la transformation avant que celle-ci ait lieu.

  8. #8
    Rédacteur

    Avatar de Erwy
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2003
    Messages
    4 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2003
    Messages : 4 967
    Points : 10 927
    Points
    10 927
    Par défaut
    En passant, je trvaille en asp (pas le .net mais le truc préhistorique..., on ne choisit pas toujours ses outils) sur de l'Oracle.

    J'utilise regulirement un mix pl-sql/sql/xml/xslt.

    J'ai en effet des requêtes qui doivent être lancé séparemment mais dont les résultat doivent être joint.
    J'ai une procédure stocké(pl/sql) qui prend en paramètre du sql et renvoi la réponse sous la forme d'un XML.
    Je récupère ces flux XML avec mon asp tout pourris.
    Je transforme ces flux en objet puis en selection de noeud via dom.
    Je passe ces sélections en paramètre à mon XSLT.
    Le XSLT fait la jointure entre les différents fichiers.

    la procédure stockée en question

    NB: Le XML sur lequel s'applique le XSLT à la base est généralement issue de la requete "principâle"

  9. #9
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    si tu as accès à un conteneur de Servlet du style Tomcat, tu peux essayer une solution assez élégante comme la servlet XSQL fournie avec le XDK d'Oracle. Cette servlet permet d'éxecuter une requête SQL contenue dans un fichier .xsql et d'en retourner le résultat au format XML via HTTP, le tout sans programmation, juste de manière déclarative.

    Il suffit donc d'une simple URL pour récupérer le résultat de la requête (si la requête est paramétrée, les paramètres sont également passés dans l'URL). Dans ton code XSLT tu feras figurer cette URL en paramètre de la fonction document(), et le tour est joué. Cela te permettra en plus d'avoir un code XSLT bien plus simple et générique, sans avoir à utiliser d'extension SQL et avec n'importe quel processeur XSLT. De manière optionnelle, tu peux définir dans ton fichier XSQL une transformation XSLT à appliquer sur le résultat de la requête.

    J'ai utilisé XSQL avec PostgreSQL, sans aucune difficulté majeure ; cela m'a évité d'utiliser les extensions XML de PostgreSQL ou de générer le XML par un script PHP, le gain de temps de développement est assez considérable. Pour finir, il existe la possibilité de demander à la servlet de déclencher un rendu PDF avec FOP. Malheureusement, je n'ai pas réussi à la faire fonctionner avec une version moderne de FOP (0.9x), elle ne fonctionne qu'avec FOP 0.20 (il est bien probable que je m'y suis pris comme un manche, étant donné qu'à priori c'est possible au prix d'un peu de programmation Java).

    Un exemple de fichier XSQL (appelons-le test.xsql) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" ?>
    <page xmlns:xsql="urn:oracle-xsql" connection="documentation">
      <xsql:include-request-params />
      <xsql:query>
        select *  from plan where id_plan = '{@id}';
      </xsql:query>
      <xsql:query>
        select * from mot_critere;
      </xsql:query>
    </page>
    On récupère le résultat de la requête par un accès à URL du style http://host.domain:80/xsql/test/test.xsql?id=61 et on récupère un résultat analogue à celui-ci :
    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
    <page>
     <request>
       <parameters>
          <id>61</id> 
        </parameters>
        <session /> 
        <cookies /> 
      </request>
     <ROWSET>
       <ROW num="1">
        <id_plan>61</id_plan> 
        <libelle_plan>Enfance et adolescence inadaptées</libelle_plan> 
        </ROW>
      </ROWSET>
      <ROWSET>
        <ROW num="1">
          <id_mot>3601</id_mot> 
          <libelle_mot>AMO</libelle_mot> 
        </ROW>
    ...
    Le résultat de chaque requête est contenu dans son propre ROWSET ; on peut paramétrer le fichier XSQL pour obtenir un résultat plus personnalisé.

    Les paramètres de la connexion (host, user, password, etc.) sont définis dans un fichier XML annexe et identifiés par une clé (dans cet exemple la clé est « documentation »). Simple, non ?
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Bonjour,

    Après m'être battu, je suis finalement arrivé à faire fonctionner la solution décrite dans le blog (cf. ma description initiale).

    Le problème venait en fait du chargement des bibliothèques Saxon. Suivant la version, je n'arrivais pas à le faire fonctionner.

    Bref, avec la 9.1, ça passe. Le code xsl est alors assez simple

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    <xsl:stylesheet
    	xmlns:saxon="http://saxon.sf.net/"
    	xmlns:sql="java:/net.sf.saxon.sql.SQLElementFactory"
     	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    	xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	xmlns:fo="http://www.w3.org/1999/XSL/Format"
    	extension-element-prefixes="saxon sql">
    (...)
     
    	<xsl:param name="driver" select="'oracle.jdbc.driver.OracleDriver'" as="xs:string"/>
    	<xsl:param name="database" select="'jdbc:oracle:thin:@server_name:port:BD'" as="xs:string"/>
    	<xsl:param name="user" select="'****'" as="xs:string"/>
    	<xsl:param name="password" select="'****'" as="xs:string"/>
     
    (...)
     
    	<xsl:if test="not(element-available('sql:connect'))">
    			<xsl:message>sql:connect is not available</xsl:message>
    	</xsl:if>
    	<xsl:if test="element-available('sql:connect')">
    		<xsl:message>sql:connect is available !! YES !</xsl:message>
    	</xsl:if>
     
    	<xsl:message>Connecting to <xsl:value-of select="$database"/>...</xsl:message>
    	<xsl:variable name="connection" 
    			as="java:java.sql.Connection"
    			xmlns:java="http://saxon.sf.net/java-type">   
    		<sql:connect driver="{$driver}" database="{$database}" 
    				user="{$user}" password="{$password}">
    			<xsl:fallback>
    				<xsl:message terminate="yes">SQL extensions are not installed</xsl:message>
    			</xsl:fallback>
    		</sql:connect>
    	</xsl:variable>
     
    	<xsl:variable name="art" select="12527"/>
     
    	<xsl:variable name="res" as="xs:string">
    		<sql:query connection="$connection"
    			table="ARTICLE" 
    			column="DESIGNATION"
    			where="NUM_ARTICLE='{$art}'"/>
    		</xsl:variable>
    	<xsl:message>Res: <xsl:value-of select="$res"/></xsl:message>
    En fait, si j'avais utilisé dès le début element-available, j'aurais pu m'apercevoir que je n'avais pas tout ce qu'il fallait dans mon classpath.

    Ensuite, il a fallu que je me batte pour que la bibliothèque Saxon n'entraîne pas d'incompatibilité avec d'autres bibliothèques que je chargeais, comme FOP par exemple. Il a fallu que j'y aille un peu au pif, essayant telle version de Saxon, avec telle autre de FOP.

    J'espère que cela pourra aider d'autres développeurs débutants en galère.

    Merci à tous d'avoir donné des réponses. Je n'ai pas toujours tout compris mais bon ...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 24/06/2010, 18h31
  2. Requête d'insertion dans une base de données
    Par Kalion dans le forum VB.NET
    Réponses: 5
    Dernier message: 25/02/2009, 13h45
  3. [MySQL] Requête mysql qui permet de chercher dans une base de données complète.
    Par your_joker dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 18/07/2008, 10h28
  4. [MySQL] Enregistrement d'une requête SQL dans une base de données MySQL
    Par glsn dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 15/07/2008, 13h06
  5. Requête dans une base de données énorme
    Par Nanji dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/06/2006, 12h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo