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 :

récupération d'index d'un fichier XML grace au XSL [XSLT 2.0]


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Futur Membre du Club
    Homme Profil pro
    ARCHIVISTE
    Inscrit en
    Novembre 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ARCHIVISTE
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2014
    Messages : 13
    Points : 7
    Points
    7
    Par défaut récupération d'index d'un fichier XML grace au XSL
    Bonjour à vous,

    Merci d'avance à tous ceux qui pourront éclairer ma lanterne. J'ai créee une feuille de style XSL 2.0 qui à partir d'un fichier XML me sort trois fichiers HTML 4. Jusque là tout va bien. J'ai juste une petite question concernant un des résultats de transformation. Voici le dilemme :

    J'ai une commande XSL qui pour chaque balise controlaccess de mon fichier XML m'extrait les mots d'index classés par ordre alpahabétique et pour chacun de ces mots d'index, me sort toutes les cotes qui s'y rapportent :

    <xsl:for-each select="//c[child::controlaccess/subject=$index]|//c[child::controlaccess/function=$index]|//c[child::controlaccess/genreform[not(@type='typir')and not(@source='liste-typedocAC')]=$index]|//c[child::controlaccess/geogname[not(@role)]=$index]|//c[child::controlaccess/persname=$index]|//c[child::controlaccess/name=$index]|//c[child::controlaccess/famname=$index]|//c[child::controlaccess/corpname[not(@altrender)]=$index]">

    <xsl:if test="child::did/unittitle[not(attribute::type)]">

    <xsl:choose>
    <xsl:when test="contains(did/unitid,'-')">
    <xsl:element name="a">
    <xsl:attribute name="href">
    <xsl:value-of select="//ead/eadheader/eadid"></xsl:value-of>notices.html#tt-<xsl:value-of select="count(ancestor::c)"></xsl:value-of>-<xsl:value-of select="did/unitid"></xsl:value-of></xsl:attribute>

    <xsl:variable name="testcaractereindexsurtitre">
    <xsl:value-of select="substring-after(./did/unitid,'/')"></xsl:value-of>
    </xsl:variable>

    <xsl:choose>
    <xsl:when test="contains($testcaractereindexsurtitre,'/')"><xsl:value-of select="did/unitid"></xsl:value-of></xsl:when>
    <xsl:otherwise>
    <xsl:choose>
    <xsl:when test="substring-after(./did/unitid,'/')"><xsl:value-of select="substring-after(did/unitid,'/')"></xsl:value-of></xsl:when>
    <xsl:otherwise><xsl:value-of select="did/unitid"></xsl:value-of></xsl:otherwise>
    </xsl:choose>

    </xsl:otherwise>
    </xsl:choose> <xsl:text> ; </xsl:text></xsl:element></xsl:when>




    Voici donc le résultat dans mon fichier HTML :

    Registre : 1 ; 1 ; 2-6 ; 2-5 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7-17 ; 7 ; 8-17 ; 8 ; 9 ; 10 ; 11 ; 12 ; 13 ; 14 ; 15 ; 16 ; 17 ; 18-19 ; 18 ; 19 ; 20 ; 21 ; 22-23 ; 22 ; 23 ; 24 ; 25 ; 29 ; 31 ; 35-36 ; 35 ; 36 ;


    ma question est la suivante, en XSL, est-il possible de simplifier le résultat à ceci ( a condition qu'on puisse vérifier que toutes les cotes de 1 à 36 sont concernés par le mot d'index):

    Registre : 1-25, 29, 31, 35-36


    Si c'est impossible en XSL est-ce possible dans un autre langage ?

    Merci d'avance de vos éclairages.

    Cordialement

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Hello,

    Dans un autre langage, ça reste assez simple : il suffit de construire au fur et à mesure la liste simplifiée, en y ajoutant tous les éléments de la liste de départ. Là comme ça, en Java ou en Python c'est pas trop dur.

    Et comme XSLT est Turing-complete, ça signifie qu'il est possible aussi de le faire en XSLT : si on peut faire un algo dans un langage quelconque, on peut faire l'équivalent en XSLT.
    ... Par contre il n'est pas franchement étudié pour, je ne te le cache pas. Là comme ça je trouve pas d'autre solution que :
    - d'abord parser ta liste de "string" vers "liste de strings qui représentent des intervalles"
    - balancer ça en paramètre d'un template récursif qui prend deux paramètres : une liste non simplifiée, et un accumulateur dans lequel on construit une liste simplifiée.

    ... Je préfère en Java ou en Python, c'est plus simple.

  3. #3
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Ce genre de besoin arrive souvent, tout au moins pas si rarissime, en fait. En xslt 2.0 avec ses facilités enrichies et les supports de typages renforcés, elle a pour buts à rendre ce genre de pattern de dessin calculateur plus soutenu et plus agile.

    Je peux vous montrer comme faire.

    [1] D'abord vous mettez une déclaration de namespace de XMLSchema (préfixe xs, dit-on) dans la racine xsl:stylesheet et puis un namespace pour des fonctions spéciales (préfixe f, dit-on) aidant les calculs.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:f="urn:tsuji-ou-n_importe_quoi"
        exclude-result-prefixes="xs f"
    >

    [2] Et puis, je fais abstraction en deux fonctions spéciales - vous pouvez faire autrement, bien entendu.
    Code xml : 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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    <xsl:function name="f:pre-proc" as="xs:integer*">
        <xsl:param name="input" as="xs:string" />
     
        <xsl:variable name="regex" select="'(-\d+)?\s*;\s*'" />
        <xsl:variable name="x" as="xs:string*" select="distinct-values(tokenize($input, $regex))" />
        <xsl:for-each select="$x">
            <xsl:sort select="number()" data-type="number" order="ascending" />
            <xsl:sequence select="xs:integer(.[normalize-space() != ''])" />
        </xsl:for-each>
     
    </xsl:function>
     
    <xsl:function name="f:proc" as="xs:string*">
        <xsl:param name="input" as="xs:integer*" />
        <xsl:param name="entry" as="xs:string" />
        <xsl:param name="seq" as="xs:string*" />
     
        <xsl:variable name="started" as="xs:boolean" 
            select="xs:boolean(string-length($entry))"
        />
     
        <xsl:choose>
            <xsl:when test="count($input)=0">
                <xsl:sequence select="$seq" />
            </xsl:when>
            <xsl:when test="count($input)=1">
                <xsl:if test="$started=false()">
                    <xsl:sequence select="($seq, $input[1])" />
                </xsl:if>
                <xsl:if test="$started=true()">
                    <xsl:sequence select="($seq, concat($entry, '-', $input[1]))" />
                </xsl:if>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="$started=true() and $input[2]=$input[1]+1">
                        <xsl:sequence select="f:proc(subsequence($input, 2, count($input)-1), $entry, $seq)" />
                    </xsl:when>
                    <xsl:when test="$started=true() and $input[2]!=$input[1]+1">
                        <xsl:sequence select="f:proc(subsequence($input, 2, count($input)-1), '', ($seq, concat($entry, '-', xs:string($input[1]))))" />
                    </xsl:when>
                    <xsl:when test="$started=false() and $input[2]=$input[1]+1">
                        <xsl:sequence select="f:proc(subsequence($input, 2, count($input)-1), xs:string($input[1]), $seq)" />
                    </xsl:when>
                    <xsl:when test="$started=false() and $input[2]!=$input[1]+1">
                        <xsl:sequence select="f:proc(subsequence($input, 2, count($input)-1), '', ($seq, xs:string($input[1])))" />
                    </xsl:when>
                    <xsl:otherwise>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>

    [2.1] La fonction f:pre-proc a pour but de remettre la donnée, un texte provenant de n'importe quel source comme vous en arrivez d'avoir et montré, pour qu'il soit mis en forme d'une séquence de xs:integer* et en plus bien ordonnée d'ordre ascendant. Et puis, la fonction f:proc cherche à sortir un texte comme besoin contenant des informations sur les séries de nombres entiers consécutifs...

    [3] Dans un template, on fait travailler les fonctions comme ça.
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <!-- en fait, la f:pre-proc permet les ordres assez aléatoire, comme bonus -->
    <xsl:variable name="givens" select="'1 ; 1 ; 2-6 ; 2-5 ; 2 ; 3 ; 4 ; 5 ; 6 ; 7-17 ; 7 ; 8-17 ; 8 ; 9 ; 10 ; 11 ; 12 ; 13 ; 14 ; 15 ; 16 ; 17 ; 18-19 ; 18 ; 19 ; 20 ; 21 ; 22-23 ; 22 ; 23 ; 24 ; 25 ; 29 ; 31 ; 35-36 ; 35 ; 36 ;'" />
    <xsl:variable name="x" select="f:pre-proc($givens)" />
    <result>
        <xsl:value-of select="f:proc($x, '', ())" />
    </result>

    Et c'est fait.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Bien vu l'aveugle, cet algo est bien plus simple que celui que j'avais en tête.
    J'ai trop travaillé avec des intervalles indénombrables.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    ARCHIVISTE
    Inscrit en
    Novembre 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ARCHIVISTE
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2014
    Messages : 13
    Points : 7
    Points
    7
    Par défaut un Grand merci
    Bonjour,

    Merci à tous les deux pour ces éclairages. je vais essayer d'utiliser ta solution Tsuji. Je vais mettre ces discussion en résolu par contre je ne dis pas je ne reviendrai pas vous embêter pour m'aider à mettre ne place cette solution. Je pense avoir grosso modo compris mais bon on verra dès que je vais me remettre dans le code c'est à dire en fin de semaine. En tout cas encore merci

    Bonne journée à vous

  6. #6
    Futur Membre du Club
    Homme Profil pro
    ARCHIVISTE
    Inscrit en
    Novembre 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ARCHIVISTE
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2014
    Messages : 13
    Points : 7
    Points
    7
    Par défaut precisions
    Bonsoir, finalement comme prévu je reviens vers vous. J'ai juste modifié la commande pour qu'au lieu de chiffres predeterminés je recupere dynamiquement une valeur aléatoire, j'ai donc seulement modifié ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <xsl:variable name="givens"><xsl:value-of select="substring-after(./did/unitid,'/')"></xsl:value-of></xsl:variable>
                                                    <xsl:variable name="x" select="f:pre-proc($givens)" />
                                                    <result>
                                                        <xsl:value-of select="f:proc($x, '', ())" />
                                                    </result>
    Or dans mon éditeur lorsque je 'associe ma feuille de style xsl à mon fichier xml, il me met le message d'erreur suivant :

    ID Système: C:\Users\uleju1\Desktop\feuille de style\hades.xsl
    Scénario: cronos
    fichier XML: C:\Users\uleju1\Desktop\feuille de style\FRAD076_IR_E_03E019.xml
    Nom du moteur: Saxon-PE 9.5.1.7
    Gravité: fatal
    Description: FORG0001: Cannot convert string "2-6" to an integer
    Emplacement de début: 15:0
    URL: http://www.w3.org/TR/2005/WD-xpath-f...1/#ERRFORG0001

    et il me place cette erreur a cette ligne :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <xsl:sequence select="xs:integer(.[normalize-space() != ''])" />
    du coup je ne vois pas bien pourquoi (je mets la feuille de style complete en pièce jointe, ce sera peut etre plus clair), est-ce parce que des fois il recupere des valeurs 2-6, du coup comment faire ?


    2° J'ai une autre question qui me semble liée, mes cotes se presente souvent sous la forme alphanumérique suivante : 1M/1/1 ou 4600W/2 ou encore 3Q3/3, donc comme vous le voyez je peux avoir plusieurs slash dans une cote, or je voudrais n'extraire que les cotes qui se trouvent après le dernier slash. Jusque là je m'en sors avec une variable puis j'ajoute un substring after

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <xsl:variable name="testcaracteresurtitre">
                                                    <xsl:value-of select="substring-after(./did/unitid,'/')"></xsl:value-of>
                                                </xsl:variable>
                                                <xsl:choose>
                                                    <xsl:when test="contains($testcaracteresurtitre,'/')">
                                                        <xsl:value-of select="./did/unitid"></xsl:value-of>
     
                                                    </xsl:when>
    mais c'est quand meme un peu bricolo bricolette parce que si j'ai trois slash du coup ma récupération échoue et du coup ma compilation de cotes pour l'index aussi...

    du coup j'espère ne pas abuser de votre temps, je vous remercie en tout cas beaucoup pour ce coup de main, si vous avez besoin d'autres infos j'essaierai d'y répondre malgré mes compétences de débutant en la matière.

    Merci à vous
    Fichiers attachés Fichiers attachés

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 559
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 559
    Points : 21 621
    Points
    21 621
    Par défaut
    Citation Envoyé par PERICLESLESTRATEGE Voir le message
    Or dans mon éditeur lorsque je 'associe ma feuille de style xsl à mon fichier xml, il me met le message d'erreur suivant :
    Oui l'exemple qui t'a été donné n'est qu'un exemple. C'est pas le travail fini, il contient pas mal d'erreurs. Mais il te met sur une bonne voie pour résoudre le problème. (Enfin, moi je préfèrerai tout de même le faire dans un autre langage, mais bon, si on veut rester sur XSLT 2 c'est une bonne voie.)

    Dans cet exemple la fonction f:pre-proc ne gère pas vraiment les intervalles tels que 1-17 ou 3-5 ou aucun intervalle. La plupart du temps elle ignore le tiret et le nombre d'après, donc 1-17 c'est juste 1 et 3-5 c'est juste 3.

    Et si jamais tu termines tes données par un intervalle, elle va planter. À cause de la regex (-\d+)?\s*;\s* qui ne s'applique pas s'il n'y a pas un ; après un - et un nombre.

    Donc il faudrait la corriger pour qu'elle gère les intervalles correctement, et je suis pas tout à fait sûr de comment faire ça simplement en XSLT 2, mais il y a peut-être moyen.

    Citation Envoyé par PERICLESLESTRATEGE Voir le message
    2° J'ai une autre question qui me semble liée, mes cotes se presente souvent sous la forme alphanumérique suivante : 1M/1/1 ou 4600W/2 ou encore 3Q3/3, donc comme vous le voyez je peux avoir plusieurs slash dans une cote, or je voudrais n'extraire que les cotes qui se trouvent après le dernier slash.
    En XSLT 2 il y a tokenize(), déjà vu dans la fonction f:pre-proc. C'est juste le split() des autres langages. Par exemple tokenize('a-b-c', '-')[last()] qui renverra simplement le c, parce que c'est la dernière lettre quand on sépare a-b-c par -

  8. #8
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    [1.1] Si $givens (ou $input à f:pre-proc) qu'on arrive par quelque moyen en réel se términe soit avec la particule ;\s* soit non, on peut s'accommoder sans grande difficulté ; je préferrerais faire une modification plus discrète dedans la fonction f:pre-proc, comme ça.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <xsl:function name="f:pre-proc" as="xs:integer*">
        <xsl:param name="input" as="xs:string" />
     
        <xsl:variable name="regex" select="'(-\d+)?\s*;\s*'" />
        <!--
        <xsl:variable name="x" as="xs:string*" select="distinct-values(tokenize($input, $regex))" />
        -->
        <xsl:variable name="x" as="xs:string*" select="distinct-values(tokenize(concat($input, ' ; '), $regex))" />
        <xsl:for-each select="$x">
            <xsl:sort select="number()" data-type="number" order="ascending" />
            <xsl:sequence select="xs:integer(.[normalize-space() != ''])" />
        </xsl:for-each>
     
    </xsl:function>
    Et c'est fait déjà avec cette liberté tenue compte.

    [2.1] Dans cette occasion, je voudrais faire un amendment sur la fonction f:proc dans la deuxième xsl:when où des castings de vairable est manquant la manière que j'ai déjà fait dans xsl:otherwise. Voici la partie en question.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
            <xsl:when test="count($input)=1">
                <xsl:if test="$started=false()">
                    <!-- [1] besoin de correction sur le casting
                    <xsl:sequence select="($seq, $input[1])" />
                    -->
                    <xsl:sequence select="($seq, xs:string($input[1]))" />
                </xsl:if>
                <xsl:if test="$started=true()">
                    <!-- [2] besoin de correction sur le casting
                    <xsl:sequence select="($seq, concat($entry, '-', $input[1]))" />
                    -->
                    <xsl:sequence select="($seq, concat($entry, '-', xs:string($input[1])))" />
                </xsl:if>
            </xsl:when>
    Les corrections là sont faites.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    ARCHIVISTE
    Inscrit en
    Novembre 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ARCHIVISTE
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2014
    Messages : 13
    Points : 7
    Points
    7
    Par défaut TENTATIVE D'APPLICATION
    Merci à tous les deux, je vais essayer d'appliquer tout ça. Etant donné que je ne suis pas informaticien, il me faut un peu plus de temps que vous pour comprendre le cheminement et je ne pourrais pas me poser avant la fin de semaine, tout ça pour dire que je ne pourrais vous en dire plus qu'en fin de semaine.

  10. #10
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Travaillez à votre rythme, sans problème. Entre-temps, je peux vous apporter quelque chose il me semble utile et tomber dans le sens vous prenez dans la donnée (givens) en ce qui concerne le "-".

    [1.2] Je prenais dans la donnée M-m comme analog à la façon qu'on fait les versions sémantiques et par conséquence je m'en prenait comme si on pouvait ignorer la version mineure m ... donc la façon je construissais f:pre-proc. Or, il se peut que vous puissiez le prendre comme une interval qu'on note en maths comme [M, m] et dans ce cas il faudrait les faire exploser tenant compter chaque nombre entier dans l'interval. Le point que je veux dire c'est précisément que c'est tout à fait faissable avec élégance en xslt 2. Pour cette compréhension, il suffit d'utiliser la version de fonction f:pre-proc ci-dessous.

    Voici comment faire le fonction f:pre-proc.
    Code xslt : 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
    <xsl:function name="f:pre-proc" as="xs:integer*">
        <xsl:param name="input" as="xs:string" />
     
        <xsl:variable name="regex" select="'\s*;\s*'" />
        <xsl:variable name="x" as="xs:string*" select="tokenize(concat($input, ' ; '), $regex)" />
     
        <xsl:variable name="y" as="xs:integer*">
            <xsl:for-each select="$x">
                <xsl:choose>
                    <xsl:when test="normalize-space() != '' and contains(., '-')">
                        <xsl:variable name="m" as="xs:integer" select="xs:integer(normalize-space(substring-before(., '-')))" />
                        <xsl:variable name="n" as="xs:integer" select="xs:integer(normalize-space(substring-after(., '-')))" />
                        <xsl:choose>
                            <xsl:when test="$m &lt; $n">
                                <xsl:sequence select="($m to $n)" />
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:sequence select="($n to $m)" />
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>
                    <xsl:when test="normalize-space() != '' and not(contains(., '-'))">
                        <xsl:sequence select="xs:integer(.)" />
                    </xsl:when>
                    <xsl:otherwise></xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </xsl:variable>
     
        <xsl:for-each select="distinct-values($y)">
            <xsl:sort select="." data-type="number" order="ascending" />
            <xsl:sequence select="." />
        </xsl:for-each>
    </xsl:function>

  11. #11
    Futur Membre du Club
    Homme Profil pro
    ARCHIVISTE
    Inscrit en
    Novembre 2014
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : ARCHIVISTE
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2014
    Messages : 13
    Points : 7
    Points
    7
    Par défaut fonction proc
    Bonjour,

    après deux semaines je reviens vers vous. En donnée d'input de la fonction pre proc, j'ai ajouté un certain nombre de contrôle pour être sûr de n'avoir en entrée que des données de type 1 ou 1-3, ce qui n'atit pas toujours le cas avec seulement cette commande. Du coup en sortie de la fonction pre proc, j'ai désormais ces données là : 1 ou bien 1 2 3 ce qui me semble bon à ce stade. Par contre du coup j'avoue que j'ai du mal à comprendre comment fonctionne la fonction proc, notamment ce que représente les variables $entry et $seq ?

    D'une manière générale, j'ai cru comprendre que la fonction proc prend en entrée le résultat de la fonction pre-proc,


    que si la donnée d'entrée est 1, alors il me redonne en sortie 1,

    <xsl:when test="count($input)=0">
    <xsl:sequence select="$seq" />
    </xsl:when>

    que si la donnée d'entrée est 1 2 3 , alors


    et que si la donnée d'entrée est 1 2 3 , la fonction cherche la première valeur et ensuite elle parse la suite numérique de 1 en 1 pour déterminer le dernier chiffre de la suite mais c'est à partir de ce moment là que je ne sais plus...

    Encore merci de toutes les infos que vous me donnez et désolé d'être aussi long a réagir.

  12. #12
    Membre émérite Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Points : 2 736
    Points
    2 736
    Par défaut
    Je ne peux que vous donner l'enchaînement de la raisonnement: je ne peux pas vous donner explication sur toutes les syntaxes nucléaires - on ne peut pas remplacer des études normalement fait par tout le monde quand on apprend quelque chose.

    La fonction pre-proc fait exploser toute les données dans la séquence originelle, c'est-à-dire si il y a un entré 4-8, il devient (4, 5, 6, 7, 8) etc... puis elle fait trier la séquence dans l'ordre ascendant numérique et aussi ne garder que les nombres distincts.

    La fonction proc consomme la séquence ainsi préparée. Elle commence par regarder le nombre le plus petit, c'est-à-dire l'entré à position 1. Si il n'y a pas c'est fini et une résultat temporaire stocké en $seq va sortir comme résultat. Si il y trouve un entré, elle va regarder le nombre qui suite. Si ce nomber est la suite naturelle du premier, elle enregistre cette trouvée par regarant la variable $entry : si $entry est vide, elle va mettre le premier nombre là et ajoute un '-' pour préparer le prochaine étape de processus; sil $entry n'est pas vide, elle ne faire pas la changer parce que la chaîne de nombre naturelle est en train de se construire. Or, si le deuxième nombre n'est pas la suite naturelle du premier, il y a donc une saute, elle va soit cloturer le $entry si elle n'est pas vide pas ajouter le premier nombre et puis charger $entry à $seq comme un entré propre et nouveau; et si $entry est vide au départ, elle met le premier nombre à $seq comme un entré nouveau.

    Après tout ça, elle va faire appeler elle-même récursivement avec la séquence comme donnée $input par éliminer le premier nombre, $entry et $sea selon les cas comme décrit dessus... ainsi de suite jusqu'à tous les nombres soit épuissé.

    Confusé ? c'est normal; ce n'est pas tout à fait une construction élémentaire... et voilà ! (Je n'ose pas à re-regarder ce que j'ai essayé à dire, c'est surement compliqué à mettre en mots les idées très organiques en fin de compte !)

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

Discussions similaires

  1. [A-02] Récupération des attributs d'un fichier xml
    Par kizou dans le forum VBA Access
    Réponses: 1
    Dernier message: 13/03/2009, 12h31
  2. Réponses: 7
    Dernier message: 27/02/2009, 16h17
  3. récupération des données d'un fichier xml ?
    Par sarapis dans le forum Flex
    Réponses: 2
    Dernier message: 10/02/2009, 11h40
  4. [XSLT]Récupération d'information dans un fichier XML
    Par LoDev dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 17/01/2008, 09h36
  5. Récupération des éléments d'un fichier xml en flux retour
    Par opeo dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 07/11/2005, 10h33

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