Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1653 connectés 

  FORUM HardWare.fr
  Programmation
  XML/XSL

  XSLT très lent

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

XSLT très lent

n°2296900
Profil sup​primé
Posté le 27-02-2017 à 20:42:54  answer
 

Bonjour,
Je reproduis une carte SVG en modifiant certains attribuer (pour la colorier) mais c'est très lent (avec libsaxonb-java).
Sachant que mon fichier svg possède quelques dizaines de milliers de polygones, et que mon fichier "communes.xml" contient à peu près le même nombre d'entrées.
Il peut prendre plus de 10 minutes à s'exécuter...  
Des idées ?
 
Merci d'avance!
 

Code :
  1. <xsl:stylesheet version="2.0"
  2.    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  3.    xmlns:xs="http://www.w3.org/2001/XMLSchema"
  4.    xmlns:doc="http://jlm2017.fr"
  5.    xmlns:fn="http://www.w3.org/2005/xpath-functions"
  6.    xmlns:dc="http://purl.org/dc/elements/1.1/"
  7.   xmlns:cc="http://creativecommons.org/ns#"
  8.   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  9.   xmlns:svg="http://www.w3.org/2000/svg"
  10.   xmlns="http://www.w3.org/2000/svg"
  11.   xmlns:xlink="http://www.w3.org/1999/xlink"
  12.   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  13.   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  14.   inkscape:version="0.48.2 r9819"
  15.   sodipodi:docname="circonscriptions.svg"
  16.    exclude-result-prefixes="xs doc">
  17.    <xsl:output method="xml" indent="yes"/>
  18.    <xsl:param name="communes" select="document('../communes.xml')"/>
  19.    <xsl:template match="@*|node()">
  20.        <xsl:copy>
  21.            <xsl:apply-templates select="@*|node()"/>
  22.        </xsl:copy>
  23.    </xsl:template>
  24.    <xsl:template match="svg:polygon">
  25.       <xsl:variable name="insee" select="substring-before(./@id, ' ')" />
  26.       <xsl:variable name="red" select="$communes//fn:map[@key=$insee]/fn:number[@key='HOLL_PRES_2012']" />
  27.        <xsl:copy>
  28.          <xsl:choose>
  29.            <xsl:when test="$red">
  30.              <xsl:attribute name="fill">rgb(255, <xsl:value-of select="255-round(255 * $red div 100)" />, <xsl:value-of select="255-round(255 * $red div 100)" /> )</xsl:attribute>
  31.            </xsl:when>
  32.            <xsl:otherwise>
  33.              <xsl:attribute name="fill">rgb(100, 100, 100)</xsl:attribute>
  34.            </xsl:otherwise>
  35.          </xsl:choose>
  36.          <xsl:apply-templates select="@*|node()" />
  37.        </xsl:copy>
  38.    </xsl:template>
  39. </xsl:stylesheet>

mood
Publicité
Posté le 27-02-2017 à 20:42:54  profilanswer
 

n°2296926
gilou
Modérateur
Modzilla
Posté le 28-02-2017 à 14:41:55  profilanswer
 

C'est clairement l'appel
select="$communes//fn:map[@key=$insee]/fn:number[@key='HOLL_PRES_2012']"
qui reparcourt ton arbre a chaque svg:polygon qui va être lent. Les // c'est coûteux en temps.
 
Il y a peut-être moyen de ne faire qu'une passe et indexer avec un xsl:key.
Par contre, il y a manifestement des bouts de code que tu n'as pas donné, car je ne comprends pas des choses comme:
fn:number[@key='HOLL_PRES_2012']
fn:number est une fonction, donc ca devrait etre qque chose comme fn:number(...)
Si tu expliques un peu mieux ce que tu veux faire, je devrais être en mesure de t'aider (si je trouve le temps, car la j'ai moi aussi plein de code xsl a écrire.)
On dirait du MarkLogic, tes fn:map et fn:number.
 
A+,


Message édité par gilou le 28-02-2017 à 16:55:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2296962
Profil sup​primé
Posté le 28-02-2017 à 18:57:10  answer
 

Merci pour ta réponse gilou,
 
En réponse à ta première remarque, j'ai modifié un peu le code  

Code :
  1. <xsl:stylesheet version="2.0"
  2.    <xsl:variable name="communes" select="document('../communes.xml')/fn:map"/>
  3. ...
  4.       <xsl:variable name="red" select="$communes/fn:map[@key=$insee]/fn:number[@key='NON_TCE']" />


 
Le code de communes.xml est généré automatiquement (de json en XML via basex)
 

Code :
  1. <map xmlns="http://www.w3.org/2005/xpath-functions">
  2.  <map key="89370">
  3.    <number key="NONISTES_DROITE_PRES_2007">15.33</number>
  4.    <number key="POUT_PRES_2012">1.92</number>
  5.    <number key="BOVE_PRES_2007">0.70</number>
  6.    <number key="NONISTES_2012">35.61</number>
  7.    <number key="LEPE_PRES_2007">11.50</number>
  8.    <number key="SCHI_PRES_2007">0.93</number>
  9.    <number key="LAGU_PRES_2007">1.86</number>
  10.    <number key="NON_TCE">59.08</number>
  11.    <number key="SARK_PRES_2007">37.17</number>
  12.    <number key="CHEM_PRES_2012">0.12</number>
  13.    <number key="BAYR_PRES_2007">16.26</number>
  14.    <number key="HOLL_PRES_2012">23.38</number>
  15.    <number key="ARTH_PRES_2012">0.36</number>
  16.    <number key="DUPO_PRES_2012">1.92</number>
  17.    <number key="BUFF_PRES_2007">2.09</number>
  18.    <number key="NIHO_PRES_2007">1.16</number>
  19.    <number key="MELE_PRES_2012">10.67</number>
  20.    <number key="BESA_PRES_2007">4.41</number>
  21.    <number key="LEPE_PRES_2012">20.74</number>
  22.    <number key="BAYR_PRES_2012">7.55</number>
  23.    <number key="NONISTES_2007">22.76</number>
  24.    <number key="VOYN_PRES_2007">0.70</number>
  25.    <number key="OUI_TCE">40.92</number>
  26.    <number key="NONISTES_DROITE_PRES_2012">22.66</number>
  27.    <number key="ROYA_PRES_2007">20.56</number>
  28.    <number key="JOLY_PRES_2012">2.16</number>
  29.    <number key="SARK_PRES_2012">31.18</number>
  30.    <number key="NONISTES_GAUCHE_PRES_2012">12.95</number>
  31.    <number key="NONISTES_GAUCHE_PRES_2007">7.43</number>
  32.    <number key="VILL_PRES_2007">2.67</number>
  33.  </map>
  34. etc.


 
Du coup comme tu le vois il y a un namespace dedans et si je n'utilise pas ce namespace fn: mes requêtes xpath échouent.
Du coup si c'est une partie du problème, je ne sais pas trop comment le régler :s

n°2296977
gilou
Modérateur
Modzilla
Posté le 28-02-2017 à 22:26:14  profilanswer
 

Ah! OK!
Mais ton namespace est bizarre alors: http://www.w3.org/2005/xpath-functions est le namespace des fonctions standard xpath, et a priori tu as ici des éléments, pas des fonctions.
Comme j'utilise SaxonEE et non Saxonb, je ne sais pas trop ce que c'est dans ton cas.
 
Bon, tu aurais xslt 3, tu pourrais utiliser les xsl:map, mais en xslt2, tu n'as que les xsl:key, et ils ne peuvent indexer que la source.
 
Ce que je ferais:
- importer tes deux fichier dans un englobant (technique  comme ici par exemple) et passer celui ci comme source de données a ta feuille de style
- passer a la trappe ce qui vient de ../communes.xml qui ne sert qu'a créer un index dans ta feuille de style, index qui associe la valeur de fn:key au sous arbre fn:map
- faire une xsl:key qui indexe les elements map avec comme cle leur attribut key
<xsl:key name="citykey" match="lfn:map[@key]" use="@key"/>
- utiliser cette xsl:key dand ton <xsl:variable name="red" select="... afin de ne chercher la donnée que sur sa liste de number, ce qui est petit, et non sur tout $communes a chaque fois
<xsl:variable name="city" select="key('citykey', substring-before(@id, ' '))"/>
<xsl:variable name="red" select="$city/fn:number[@key='HOLL_PRES_2012']" />
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2296986
Profil sup​primé
Posté le 01-03-2017 à 01:13:24  answer
 

Merci beaucoup, super cette histoire de key, je fais ça demain!

n°2297062
gilou
Modérateur
Modzilla
Posté le 01-03-2017 à 23:57:50  profilanswer
 

Autre chose: éviter l'emploi de //
Dans le code initial,
$communes//fn:map[@key=$insee]/fn:number[@key='HOLL_PRES_2012']
passe en
$communes/fn:map/fn:map[@key=$insee]/fn:number[@key='HOLL_PRES_2012']
aurait sans doute été un poil plus efficace
 
Sinon, après avoir parlé avec le guru XML de ma boite, il y a une astuce avec key permettant de l'utiliser sur un document précis: c'est pas avec la définition xsl:key, mais a la première invocation avec le 3e paramètre.
Ça permet de se passer des contorsions indiquées vis a vis des fichiers comme indique dans mon post précédent.  
Il suffit juste de transformer ton code comme suit:
 

Code :
  1. <xsl:stylesheet version="2.0"
  2.         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  3.         xmlns:xs="http://www.w3.org/2001/XMLSchema"
  4.         xmlns:doc="http://jlm2017.fr"
  5.         xmlns:fn="http://www.w3.org/2005/xpath-functions"
  6.         xmlns:dc="http://purl.org/dc/elements/1.1/"
  7.         xmlns:cc="http://creativecommons.org/ns#"
  8.         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  9.         xmlns:svg="http://www.w3.org/2000/svg"
  10.         xmlns="http://www.w3.org/2000/svg"
  11.         xmlns:xlink="http://www.w3.org/1999/xlink"
  12.         xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  13.         xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  14.         inkscape:version="0.48.2 r9819"
  15.         sodipodi:docname="circonscriptions.svg"
  16.         exclude-result-prefixes="xs doc">
  17.  <xsl:output method="xml" indent="yes"/>
  18.  <xsl:param name="communes" select="document('../communes.xml')"/>
  19.  <xsl:key name="citykey" match="fn:map[@key]" use="@key"/>
  20.  <xsl:template match="@*|node()">
  21.    <xsl:copy>
  22.      <xsl:apply-templates select="@*|node()"/>
  23.    </xsl:copy>
  24.  </xsl:template>
  25.  <xsl:template match="svg:polygon">
  26.    <xsl:variable name="insee" select="substring-before(./@id, ' ')" />
  27.    <xsl:variable name="city" select="key('citykey', substring-before(@id, ' '), $communes)"/>
  28.    <xsl:variable name="red" select="$city/fn:number[@key='HOLL_PRES_2012']" />
  29.    <xsl:copy>
  30.      <xsl:choose>
  31.     <xsl:when test="$red">
  32.       <xsl:attribute name="fill">rgb(255, <xsl:value-of select="255-round(255 * $red div 100)" />, <xsl:value-of select="255-round(255 * $red div 100)" /> )</xsl:attribute>
  33.     </xsl:when>
  34.     <xsl:otherwise>
  35.       <xsl:attribute name="fill">rgb(100, 100, 100)</xsl:attribute>
  36.     </xsl:otherwise>
  37.      </xsl:choose>
  38.      <xsl:apply-templates select="@*|node()" />
  39.    </xsl:copy>
  40.  </xsl:template>
  41. </xsl:stylesheet>


Et tu peux peut etre encore gagner un chouia de perf en ne calculant qu'une fois, dans une variable la valeur 255-round(255 * $red div 100) et en la réutilisant.
 
A+,


Message édité par gilou le 14-12-2017 à 23:30:05

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2297068
Profil sup​primé
Posté le 02-03-2017 à 01:36:52  answer
 

Merci beaucoup! Tu as répondu avant que je puisse m'y atteler à nouveau.
Ça marche du tonnerre!  
J'avais jamais utilisé les key, XSL m'étonne toujours, vraiment très puissant :)

n°2297070
gilou
Modérateur
Modzilla
Posté le 02-03-2017 à 02:11:25  profilanswer
 

Et xsl 3, qui devrait passer au statut de "proposed recommendation" d'ici un mois environ est bien plus puissant encore (try/catch, iterate...) en particulier avec les fonctions xpath évoluées.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  XML/XSL

  XSLT très lent

 

Sujets relatifs
Aide SQL très simpleCode VBA trop lent
Idée Programation jeux video TRES COMPLEXEremplacer des mots par des liens (XML to HTML via XSLT)
Une très bête question "and" comme "or"?Bonnes pratiques pour une gestion de stocks très basique
Script très léger pour activer les touches du clavier ?Recherche script de grid tres performant
Programme qui est de plus en plus lentTrès étrange problème de sheets.select
Plus de sujets relatifs à : XSLT très lent


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR