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 :

Suppression d'une balise avec condition


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Candidat au Club
    Suppression d'une balise avec condition
    Bonjour,

    Je dois faire une transformation XSL et je n'en ai jamais fait auparavant.
    J'ai lu un peu le forum et le Web pour réussir a sortir un premier fichier, mais je ne sais pas comment ajouter une condition et donc je fais appel a vous.

    J'ai des fichiers qui contiennent un certain nombre d'acte (medicaux) qui est de la forme suivante :
    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
    50
    51
    <?xml version="1.0" encoding="UTF-8"?>
    <evenementsServeurActes acquittementAttendu="oui" identifiantAttendu="non" version="2.00">
    	<evenementServeurActe>
    		<actesNGAP>
    			<acteNGAP action="création" executionDimancheJourFerie="non" executionNuit="non" facturable="oui" gratuit="non" porteeCle="l" valide="oui">
    				<identifiant>
    					<emetteur>275449488</emetteur>
    				</identifiant>
    				<lettreCle>FTPU</lettreCle>
    				<coefficient>1</coefficient>
    				<denombrement>1</denombrement>
    				<quantite>1</quantite>
    				<execute>
    					<date>2019-05-29</date>
    					<heure>12:00:00</heure>
    				</execute>
    				<prestataire>
    					<medecins>
    						<medecin lien="prsc">
    							<numeroAdeli>123456789</numeroAdeli>
    							<personne>
    								<nomUsuel>MEDECIN1</nomUsuel>
    								<prenoms>
    									<prenom>PrenomMed1</prenom>
    								</prenoms>
    							</personne>
    						</medecin>
    					</medecins>
    					<uniteFonctionnelle>
    						<code>5000</code>
    						<libelle>IMAGERIE MEDICALE</libelle>
    						<dictionnaire>r2i</dictionnaire>
    					</uniteFonctionnelle>
    				</prestataire>
    				<minorMajor>
    					<minoration>
    						<pourcentage>85</pourcentage>
    						<coefficient>0.85</coefficient>
    					</minoration>
    				</minorMajor>
    				<montant liberal="non">
    					<montantTotal>14.03</montantTotal>
    					<numeroForfaitTechnique>4141</numeroForfaitTechnique>
    					<numeroAgrementAppareil>83779</numeroAgrementAppareil>
    					<quantite>1</quantite>
    					<numeroFacture>1392541419</numeroFacture>
    				</montant>
    			</acteNGAP>
    		</actesNGAP>
    	</evenementServeurActe>
    </evenementsServeurActes>


    j'ai besoin pour les actes dont la balise 'lettreCle' est égale à FTPU ou IFTP de supprimer la balise 'pourcentage' avec sa valeur associé dans le cas ou elle est présente.

    J'ai donc écrit ma toute première transformation qui fonctionne correctement sur mes premiers tests :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <xsl:stylesheet version="1.0" xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
    	<xsl:template match="node() | @*">
    		<xsl:copy>
    			<xsl:apply-templates select="@* | node()"/>
    		</xsl:copy>
    	</xsl:template>
    	<xsl:template match="//minorMajor/minoration/pourcentage" />
    </xsl:stylesheet>


    Mais je ne sais pas comment l'appliquer uniquement au balise 'lettreCle' égale à 'FTPU' ou 'IFTP'.

    Merci à ceux qui pourront me venir en aide.

  2. #2
    Modérateur

    Hello,

    le plus simple est de se servir d'un prédicat :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="//acteNGAP[lettreCle = 'FTPU' or lettreCle = 'IFTP']/minorMajor/minoration/pourcentage">
      <!-- volontairement vide -->
    </xsl:template>
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre émérite
    Comme ça ?
    Code xslt :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <xsl:template match="pourcentage[
        normalize-space(preceding::lettreCle[1])='FTPU' 
        or
        normalize-space(preceding::lettreCle[1])='IFTP'
        ]"
    />

    Pour tester sur text(), plus que souvent, utiliser normalize-space() en plus rend le prédicat beaucoup plus solid, sinon pas toujours nécessaire.

  4. #4
    Candidat au Club
    Bonjour,

    Citation Envoyé par thelvin Voir le message
    le plus simple est de se servir d'un prédicat :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    <xsl:template match="//acteNGAP[lettreCle = 'FTPU' or lettreCle = 'IFTP']/minorMajor/minoration/pourcentage">
      <!-- volontairement vide -->
    </xsl:template>
    Je viens de tester sur un lot de 400 actes et cela me semble parfaitement fonctionner.

    J'ose la question subsidiaire du néophite, si j'ai un second type de ligne à supprimer, il faut que je refasse une transformation et que je l'applique ensuite ou puis-je rajouter un "xsl:template match" à la suite du premier (après la balise fermante cela s'entend) ?

    Et le petit supplément pour finir, un bon bouquin ou site a conseiller pour maitriser le XSLT ?

    Merci,
    Bonne journée

  5. #5
    Modérateur

    Tu peux simplement rajouter un nouveau template.

    Hélas, je ne me souviens plus du titre du bouquin avec lequel j'ai appris. Je ne sais quoi dire comme ressource pour apprendre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre émérite
    Et le petit supplément pour finir, un bon bouquin ou site a conseiller pour maitriser le XSLT ?
    Je peux avancer sans réserve
    1) Micheal Van Otegem, Sams Teach Yourself XSLT in 21 Days (1st Edition), Sams Publishing, 2002.
    2) Micheal Kay, XSLT 2.0 and XPath 2.0 Programmer's Reference (4th Edition), Wrox, 2008. (ou plus à jour, si il y en a)
    Le 1) peut vous surprise comme trop élémentaire, non, c'est même le meilleur à mon sens, pour le niveau et au delà.
    Et puis, je pense, si on veut, que ceci puisse être consulté avec profit pour certains
    3) Sal Mangano, XSLT Cookbook: Solutions and Examples for XML and XSLT Developers (2nd Edition), O'Reilly, 2005.
    Voilà !

  7. #7
    Candidat au Club
    Citation Envoyé par tsuji Voir le message
    Je peux avancer sans réserve
    1) Micheal Van Otegem, Sams Teach Yourself XSLT in 21 Days (1st Edition), Sams Publishing, 2002.
    2) Micheal Kay, XSLT 2.0 and XPath 2.0 Programmer's Reference (4th Edition), Wrox, 2008. (ou plus à jour, si il y en a)
    Le 1) peut vous surprise comme trop élémentaire, non, c'est même le meilleur à mon sens, pour le niveau et au delà.
    Et puis, je pense, si on veut, que ceci puisse être consulté avec profit pour certains
    3) Sal Mangano, XSLT Cookbook: Solutions and Examples for XML and XSLT Developers (2nd Edition), O'Reilly, 2005.
    Voilà !
    Merci beaucoup pour ces références.
    Je vais chercher ça

  8. #8
    Membre du Club
    Bonjour,
    Je me permets de rebondir sur ce post car je travaille sur des fichiers de même norme: actes H'XML.
    J'ai plusieurs occurrences de <acteNGAP> et je voudrais supprimer cette balise et ses fils si lettreCle a une certaine valeur.

    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
     
    <actesNGAP>
    	<acteNGAP action="création" gratuit="oui" facturable="non" executionNuit="non" executionDimancheJourFerie="non">
    		<identifiant>
    			<emetteur>XX</emetteur>
    			<recepteur>0</recepteur>
    		</identifiant>
    		<lettreCle>FDI</lettreCle>
    		<coefficient>1</coefficient>
    		<execute>
    			<date>2020-05-15</date>
    			<heure>15:00:00</heure>
    		</execute>
    		..........
    	</acteNGAP>
    	<acteNGAP action="création" gratuit="oui" facturable="non" executionNuit="non" executionDimancheJourFerie="non">
    		<identifiant>
    			<emetteur>YY</emetteur>
    			<recepteur>0</recepteur>
    		</identifiant>
    		<lettreCle>CSI</lettreCle>
    		<coefficient>1</coefficient>
    		<execute>
    			<date>2020-05-15</date>
    			<heure>15:00:00</heure>
    		</execute>
    		...........
    	</acteNGAP>
    </actesNGAP>


    J'ai essayé le code suivant mais sans succès

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    <xsl:template match="//acteNGAP[lettreCle ='FDI']/*">
    </xsl:template>


    Merci de vos suggestions

  9. #9
    Membre émérite
    Comme ça.
    Code xslt1 :Sélectionner tout -Visualiser dans une fenêtre à part
    <xsl:template match="actNGAP[normalize-space(lettreCle)='FDI']" />

  10. #10
    Membre du Club
    Merci, ça fonctionne nickel.

    J'aurais une autre question.
    J'ai essayé de passer en paramètre la valeur de lettreCle à supprimer en remplaçant FDI par un $param.
    ça ne fonctionnait pas.

    J'ai donc repris le code comme ceci :
    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
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns<img src="images/smilies/icon_mad.gif" border="0" alt="" title=":x" class="inlineimg" />sl="http://www.w3.org/1999/XSL/Transform">
    	<!-- suppression lettreCle -->
    	<xsl:param name="conditionTrue">lettreCle</xsl:param>
    	<xsl:template match="@*|node()">
    		<xsl:copy>
    			<xsl:choose>
    				<xsl:when test="name()='acteNGAP'">
    				<xsl:if test="following::lettreCle[1]=$conditionTrue"></xsl:if>
    				<xsl:if test="following::lettreCle[1]!=$conditionTrue"><xsl:apply-templates select="@*|node()"/></xsl:if>
    				</xsl:when>
    				<xsl:otherwise>
    					<xsl:apply-templates select="@* | node()"/>
    				</xsl:otherwise>	
    			</xsl:choose>
    		</xsl:copy>
    	</xsl:template>
    </xsl:stylesheet>


    ça fonctionne sauf qu'il recopie la balise acteNGAP quand la condition est vraie, alors que je voudrais supprimer toute l'occurence

  11. #11
    Modérateur

    Hello,

    recopier la balise, c'est ce que fait <xsl:copy>.

    Du coup si tu ne veux le faire que dans certaines conditions, <xsl:copy> ne doit être mis que dans ces conditions.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Membre émérite
    Le langage de xslt a des règles de priorité qu'il faut bien appliquer à un bon fin. En plus, le template @match supporte bien le paramètre sauf des moteurs très archaiques, peut-être. Laissez le template de transformation identique tel quel, inchangé, et ajoutez un template spécifique de la façon que j'ai répondu aupravant (là, il y avait un typo acteNGAP au lieu de actNGAP, bien-entendu).
    Code xslt :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    <!-- xsl:param name="conditionTrue">lettreCle</xsl:param -->
    <xsl:param name="conditionTrue">FDI</xsl:param>
    <xsl:template match="acteNGAP[normalize-space(lettreCle)=$conditionTrue]" />


    Si vous voulez le faire en modifiant le template de tranformation identique, c'est faisable, bien-entendu, mais la logique est défective ... et l'emploi de l'axe following manque de rigueur. En tout cas, la solution est beaucoup moins parlant que la première, à mon sens.
    Code xslt1 :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
    	<!-- suppression lettreCle -->
    	<!-- xsl:param name="conditionTrue">lettreCle</xsl:param -->
    	<xsl:param name="conditionTrue">FDI</xsl:param>
    	<xsl:template match="@*|node()">
    
    			<xsl:choose>
    				<xsl:when test="name()='acteNGAP'">
    				<xsl:if test="normalize-space(child::lettreCle)=$conditionTrue"></xsl:if>
    				<xsl:if test="normalize-space(child::lettreCle)!=$conditionTrue">
                                        <xsl:copy>
                                            <xsl:apply-templates select="@*|node()"/>
                                        </xsl:copy>
                                    </xsl:if>
    				</xsl:when>
    				<xsl:otherwise>
                                         <xsl:copy>
    					<xsl:apply-templates select="@* | node()"/>
                                         </xsl:copy>
    				</xsl:otherwise>	
    			</xsl:choose>
    		
    	</xsl:template>

  13. #13
    Membre du Club
    La première solution fonctionne parfaitement.
    Merci.