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 :

Probleme de xsl:template : ne s'applique pas dans tous les cas


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre régulier
    Probleme de xsl:template : ne s'applique pas dans tous les cas
    Bonjour,

    Je possède un fichier XML que je souhaite transformer en un autre fichier XML à l'aide d'un fichier XSLT.
    Je souhaite que lorsque un id de friendlyUnit (qui peut avoir comme suite soit unit soit ennemyUnit) soit de sorte %:0:%, on vérifie que
    tacticalData/commandAndControlRole soit différent de 0 ou 1. Si ce n'est pas le cas, on le passe à 2.

    Voici le contenu de mon XML

    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
     
    ?xml version="1.0" encoding="UTF-8"?>
    <NC1_OWNSITREP xmlns="urn:fra:nc1:message:ownsitrep" classification="0" mediumVersion="1"
        minorVersion="0" urgencyLevel="0">
        <ownForcesTaskOrganizationAndPresence xmlns="">
            <friendlyUnit>
                <unit id="0:0:0" lastChangeDatetime="2019-07-03T07:15:03.867Z"
                    majorVersion="8" mediumVersion="1" minorVersion="0">
                    <extFunction xmlns:sics="http://atos.net/ns/sics">
                        <sics:sioc>sics</sics:sioc>
                    </extFunction>
                    <tacticalData>
                        <name>PC1</name>
                        <idOps>0425</idOps>
                        <commandAndControlRole>1</commandAndControlRole>
                    </tacticalData>
                </unit>
            </friendlyUnit>
            <friendlyUnit>
                <ennemyUnit id="34:0:106" lastChangeDatetime="2019-07-03T08:00:48.451Z"
                    majorVersion="8" mediumVersion="1" minorVersion="0">
                    <tacticalData>
                        <name>PC1</name>
                        <idOps>425</idOps>
                        <commandAndControlRole>0</commandAndControlRole>
                    </tacticalData>
                </ennemyUnit>
            </friendlyUnit>
        </ownForcesTaskOrganizationAndPresence>
        <controlAndCoordinationMeans xmlns=""/>
    </NC1_OWNSITREP>


    Et voici le contenu de mon XSLT, qui fait la transformation sur le 2eme cas, mais pas sur le 1er (sachant que je peux avoir des dizaines de cas dans un fichier plus gros).
    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
    45
    46
    47
    48
    49
     
    ?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sl="http://www.w3.org/1999/XSL/Transform"
        xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />s="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="xs"
        version="2.0">
        <xsl:output
            method="xml"
            encoding="UTF-8"
            indent="yes" 
        />
     
        <!-- On cherche les documents XML entiers -->
        <xsl:template match="/">
            <!-- On cherche tous les documents XML dans le même répértoire -->
            <xsl:for-each select="collection('./?select=*.xml')" >
                <!-- On recopie les fichiers XML de sorties dans le dossier 'resultat' avec les mêmes noms que les fichiers de départ -->
                <xsl:result-document method="xml" href="resultat/{tokenize(document-uri(.), '/')[last()]}">
                    <xsl:copy>
                        <xsl:apply-templates select="node()|@*"/>
                    </xsl:copy>
                </xsl:result-document>
            </xsl:for-each>
        </xsl:template>
     
        <!-- Permet de recopier tous les noeuds dans le nouveau fichier -->
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
     
        <!-- Remplace "context" par "instance" -->
        <xsl:template match="//*/@context">
            <xsl:attribute name="instance"><xsl:value-of select="."/></xsl:attribute>
        </xsl:template>
     
        <xsl:template match="//*/friendlyUnit/*[preceding::node()[@id[contains(., ':0:')]]]/tacticalData/commandAndControlRole">
            <xsl:copy>
                <xsl:if test=". &gt; 1">
                    <xsl:value-of select="."/>
                </xsl:if>
                <!-- Dans le cas de la règle schématron 19 d'OWNSITREP, on remplace 0 ou 1 par 2 -->
                <xsl:if test=". &lt; 2">
                    <xsl:value-of select="2"/>
                </xsl:if>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

  2. #2
    Modérateur

    Hello,

    il y a pas d'id dans ton truc. Il faut montrer un vrai exemple.

    Cela dit, en général l'axe preceding:: démontre qu'on s'y prend mal. Bon, ça arrive qu'il soit utile, mais ça y ressemble pas avec ce que tu nous décris.
    Et de toute façon, preceding::node() va forcément sélectionner l'espace blanc entre deux éléments.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Citation Envoyé par thelvin Voir le message
    Hello,

    il y a pas d'id dans ton truc. Il faut montrer un vrai exemple.

    Cela dit, en général l'axe preceding:: démontre qu'on s'y prend mal. Bon, ça arrive qu'il soit utile, mais ça y ressemble pas avec ce que tu nous décris.
    Et de toute façon, preceding::node() va forcément sélectionner l'espace blanc entre deux éléments.
    Woops, c'est modifier dans le 1er post, et je reposte le XML ici aussi du coup

    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
     
    ?xml version="1.0" encoding="UTF-8"?>
    <NC1_OWNSITREP xmlns="urn:fra:nc1:message:ownsitrep" classification="0" mediumVersion="1"
        minorVersion="0" urgencyLevel="0">
        <ownForcesTaskOrganizationAndPresence xmlns="">
            <friendlyUnit>
                <unit id="0:0:0" lastChangeDatetime="2019-07-03T07:15:03.867Z"
                    majorVersion="8" mediumVersion="1" minorVersion="0">
                    <extFunction xmlns:sics="http://atos.net/ns/sics">
                        <sics:sioc>sics</sics:sioc>
                    </extFunction>
                    <tacticalData>
                        <name>PC1</name>
                        <idOps>0425</idOps>
                        <commandAndControlRole>1</commandAndControlRole>
                    </tacticalData>
                </unit>
            </friendlyUnit>
            <friendlyUnit>
                <ennemyUnit id="34:0:106" lastChangeDatetime="2019-07-03T08:00:48.451Z"
                    majorVersion="8" mediumVersion="1" minorVersion="0">
                    <tacticalData>
                        <name>PC1</name>
                        <idOps>425</idOps>
                        <commandAndControlRole>0</commandAndControlRole>
                    </tacticalData>
                </ennemyUnit>
            </friendlyUnit>
        </ownForcesTaskOrganizationAndPresence>
        <controlAndCoordinationMeans xmlns=""/>
    </NC1_OWNSITREP>


    EDIT : Effectivement, la suppression de preceding::node() m'a permis de corriger mon problème. Merci !

    Voici l'extrait de code corrigé
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        <xsl:template match="//*/friendlyUnit/*[@id[contains(., ':0:')]]/tacticalData/commandAndControlRole">
            <xsl:copy>
                <xsl:if test=". &gt; 1">
                    <xsl:value-of select="."/>
                </xsl:if>
                <!-- Dans le cas de la règle schématron 19 d'OWNSITREP, on remplace 0 ou 1 par 2 -->
                <xsl:if test=". &lt; 2">
                    <xsl:value-of select="2"/>
                </xsl:if>
            </xsl:copy>
        </xsl:template>

  4. #4
    Modérateur

    Bien joué !
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java