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

XML/XSL et SOAP Discussion :

Transfomer XLM via XLS avec imbrication


Sujet :

XML/XSL et SOAP

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2008
    Messages : 7
    Points : 8
    Points
    8
    Par défaut Transfomer XLM via XLS avec imbrication
    Bonjour,
    j'ai un fichier XML dans lequel il y a des informations qui se suivent sans liens particuliers.
    J'ai d'abord un ensemble de factures (entre <Sale> et </Sale>) et après, suit un ensemble de détails (entre <Détail> et </Détail>).
    J'essaye de transformer ce fichier XML au moyen d'un fichier XLS. Je souhaite lors de cette transformation faire une imbrication de sorte que pour chaque <Sale> correspondent plusieurs <Detail>. En effet à chaque ''OurRef'' dans <Sale> correspond plusieurs ''Ref'' dans <Detail>. Exemple dans un extrait du fichier ci-dessous : à ''OurRef'' 148214 dans <Sale> correspond deux ''Ref'' 148214 dans <Detail>. Il me semble qu'il devrait être possible au moyen d'un fichier XSL de transformer ce fichier XML (sans les imbrications) en un autre fichier XML (avec les imbrications), mais je n'y arrive pas.
    voici quelques lignes qui illustrent le fichier 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
    32
    33
    34
    35
    36
    37
    38
    39
     
    <?xml version="1.0" encoding="UTF-8"?>
    -<dataroot generated="2014-04-24T15:51:47" xmlns:od="urn:schemas-microsoft-com:officedata">
    -<Sale>
    <Customer_Prime>540</Customer_Prime>
    <OurRef>148214/</OurRef>
    <Amount>146,49</Amount>
    ...
    </Sale>
    -<Sale>
    <Customer_Prime>612</Customer_Prime>
    <OurRef>148058/</OurRef>
    <Amount>2988,09</Amount>
    ...
    </Sale>
    -<Detail>
    <Account>400000</Account>
    <Amount>147,59</Amount>
    <Ref>148214/</Ref>
    ...
    </Detail>
    -<Detail>
    <Account>700300</Account>
    <Amount>139,38</Amount>
    <Ref>148214/</Ref>
    ...
    </Detail>
    -<Detail>
    <Account>400000</Account>
    <Amount>3008,42</Amount>
    <Ref>148058/</Ref>
    </Detail>
    -<Detail>
    <Account>701000</Account>
    <Amount>32,73</Amount>
    <Ref>148058/</Ref>
    ...
    </Detail>
    </dataroot>
    Voici au complet le fichier XSL :
    Mon ''xsl:if test'' ne fonctionne pas et même si je l'enlève, les deux ''for-each'' ne me donnent pas le résultat souhaité.
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    	<xsl:template match="//dataroot">
    		<ImportExpMPlus>
    			<Sales>
    				<xsl:for-each select="Sale">
    					<Sale>
    						<Journal_Prime>
    							<xsl:value-of select="Journal_Prime"/>
    						</Journal_Prime>
    						<Customer_Prime>
    							<xsl:value-of select="Customer_Prime"/>
    						</Customer_Prime>
    						<CurrencyCode>
    							<xsl:value-of select="CurrencyCode"/>
    						</CurrencyCode>
    						<DocType>
    							<xsl:value-of select="DocType"/>
    						</DocType>
    						<DocNumber>
    							<xsl:value-of select="DocNumber"/>
    						</DocNumber>
    						<DocDate>
    							<xsl:value-of select="DocDate"/>
    						</DocDate>
    						<DueDate>
    							<xsl:value-of select="DueDate"/>
    						</DueDate>
    						<OurRef>
    							<xsl:value-of select="OurRef"/>
    						</OurRef>
    						<YourRef>
    							<xsl:value-of select="YourRef"/>
    						</YourRef>
    						<Amount>
    							<xsl:value-of select="Amount"/>
    						</Amount>
    						<Discount>
    							<xsl:value-of select="Discount"/>
    						</Discount>
    						<AccountingPeriod>
    							<xsl:value-of select="AccountingPeriod"/>
    						</AccountingPeriod>
    						<VATMonth>
    							<xsl:value-of select="VATMonth"/>
    						</VATMonth>
    						<Year_Alfa>
    							<xsl:value-of select="Year_Alfa"/>
    						</Year_Alfa>
    						<Ventil>
    							<xsl:value-of select="Ventil"/>
    						</Ventil>
    						<VATAmount>
    							<xsl:value-of select="VATAmount"/>
    						</VATAmount>
    						<Status>
    							<xsl:value-of select="Status"/>
    						</Status>
    						<Rate>
    							<xsl:value-of select="Rate"/>
    						</Rate> 
    							<Details>
    								<xsl:for-each select="Detail">
    									<xsl:if test="Ref=YourRef">
    										<Detail>
    											<Account>
    												<xsl:value-of select="Account"/>
    											</Account>
    											<Amount>
    												<xsl:value-of select="Amount"/>
    											</Amount>
    											<DebCre>
    												<xsl:value-of select="DebCre"/>
    											</DebCre>
    											<Ventil>
    												<xsl:value-of select="Ventil"/>
    											</Ventil>
    											<Ref>
    												<xsl:value-of select="Ref"/>
    											</Ref>
    											<Unit1>
    												<xsl:value-of select="Unit1"/>
    											</Unit1>
    											<Unit2>
    												<xsl:value-of select="Unit2"/>
    											</Unit2>
    										</Detail>
    									</xsl:if>
    								</xsl:for-each>
    							</Details>
    					</Sale>
    				</xsl:for-each>
    			</Sales>
    		</ImportExpMPlus>
    	</xsl:template>
    </xsl:stylesheet>
    Qu'en pensez-vous ? Mon approche est-elle sensée/réalisable ? Si oui, où seraient les erreurs dans le XLS ? Merci. Cordialement. Richard

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 64
    Points : 58
    Points
    58
    Par défaut
    Bonjour,
    Puis-je te suggérer de donner un exemple souhaité du fichier résultant de telle manière que l'on puisse bien comprendre.
    Deuxième suggestion, pourrais-tu faire un petit algorhytme afin de "matérialiser" tes ruptures et les actions souhaitées, ça peut aider à transposer en langage xsl.
    Cordialement.

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Personnellement je trouve, et c'est assez rare pour mériter des éloges, que le résultat voulu est présenté assez clairement, de même que l'algorithme général employé, à l'aide de l'exemple XSLT.
    C'est vrai qu'avoir un vrai exemple du résultat, c'est pas plus mal. L'algorithme... Désolé, je le trouve suffisamment évident. Moi ce que j'aurais voulu, c'est que l'exemple soit simplifié et mieux présenté. <Journal_Prime>, <Customer_Prime>, ça sert à rien ces trucs, il sera toujours temps de les mettre une fois le problème résolu.
    Mais bon, l'effort est déjà pas mal comme ça.

    Voici donc une aide : tu ne peux pas faire select="Detail" à l'intérieur de <xsl:for-each select="Sale">. La raison pour laquelle le for-each sur Sale fonctionne, c'est parce que les <Sale> sont des enfants de <dataroot> et que le for-each est appliqué pendant que tu travailles sur un <dataroot>.
    Mais en faisant le for-each, à l'intérieur tu travailles sur le <Sale> sélectionné. Et <Detail> n'est pas un enfant de <Sale>, raison donc pour laquelle select="Detail" ne peut pas marcher.
    Il faut demander à sélectionner tous les <Detail>, et non pas juste ceux qui sont enfants du <Sale> en cours. Tu l'as fait pour le template qui s'applique sur tous les <dataroot>, même syntaxe pour demander tous les <Detail>.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2002
    Messages
    64
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2002
    Messages : 64
    Points : 58
    Points
    58
    Par défaut
    Bonjour,
    Je ne veux pas polémiquer.
    Un exemple du résultat attendu est toujours un plus, cela évite les ambiguités, et, quelques fois, on comprend tout seul son erreur.
    Pour l'algorhitme, le gros avantage est que, quand tu dois l'écrire en "pseudo-code", forcément à un moment tu devrait voir si ce que tu écris est possible ou non.
    Or - et je suis bien placé pour le savoir - quand on "saute" cette étape, on raisonne dans sa tête et on écrit directement le code, et on cherche pendant 3 heures pourquoi ça ne fonctionne pas alors que le code est "correct" (sans bug).
    Si on teste "à la main" suivant son algorhitme, il arrive un moment où on se traite de tous les noms en se disant : "Mais ! On peut pas accéder à cette données @$£* !!!"
    En suivant une session sur le XPath, je me suis trouvé souvent dans ce cas : Le pointeur était ailleurs où je l'imaginais (dans ma tête) - L'ordinateur est stupide, il devrait comprendre tout seul nos erreurs et les rectifier en douce sans nous le dire.
    Bref, les joies de la programmation.
    Cordialement.

  5. #5
    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
    @RonSde
    Vous avez ceci
    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
    <xsl:template match="//dataroot">
        <ImportExpMPlus>
            <Sales>
                <xsl:for-each select="Sale">
                    <Sale>
                        <!-- etc etc -->
                        <Details>
                            <xsl:for-each select="Detail">
                                <xsl:if test="Ref=YourRef">
                                    <Detail>
                                        <!-- etc etc -->
                                    </Detail>
                                </xsl:if>
                            </xsl:for-each>
                        </Details>
                    </Sale>
                </xsl:for-each>
            </Sales>
        </ImportExpMPlus>
    </xsl:template>
    Cela pose pas mal de problèmes.
    [1] Le plus évident c'est que ça veut dire xsl:for-each Detail comme enfant de Sale, pas comme enfant de dataroot. Il faut donc mettre une correction...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                           <xsl:for-each select="../Detail">
    [2] Et puis, ça c'est important, c'est que le contexte courant une fois dépassée cette ligne-là est passé de Sale à Detail. Donc, vous ne pouvez retrouver la réference de Sale sans préparation. Je veux dire le noeud teste
    <xsl:if test="Ref=YourRef">
    ne réussirait jamais. (D'ailleurs, c'est OurRef que vous vouliez dire, je pense.) Comme le contexte de Sale est déjà perdu, il faut préparer d'avance.
    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
                <xsl:for-each select="Sale">
                    <Sale>
                        <xsl:variable name="OurRef" select="OurRef" />    <!-- ajouter -->
                        <!-- etc etc -->
                        <Details>
                            <xsl:for-each select="../Detail">
                                <xsl:if test="Ref=$OurRef">    <!-- correction -->
                                    <Detail>
                                        <!-- etc etc -->
                                    </Detail>
                                </xsl:if>
                            </xsl:for-each>
                        </Details>
                    </Sale>
                </xsl:for-each>
    [3] Il y a une fonction current() qui peut trouver le contexte courant. On peut s'en servir avec pour trouver le contexte de Sale - donc, Sale/OurRef. Mais il ne faut pas s'en servir trop tard et c'est important. On s'en serve dans un prédicat on construit pour l'attribut match. Comme ça, on retire en plus le teste xsl:if et ça simplifie les choses aussi
    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:for-each select="Sale">
                    <Sale>
                        <!-- etc etc -->
                        <Details>
                            <xsl:for-each select="../Detail[Ref=current()/OurRef]">    <!-- modifiée -->
                                <!-- <xsl:if test="Ref=YourRef"> -->    <!-- retirée -->
                                    <Detail>
                                        <!-- etc etc -->
                                    </Detail>
                                <!-- </xsl:if> -->    <!-- retirée -->
                            </xsl:for-each>
                        </Details>
                    </Sale>
                </xsl:for-each>
    Voilà !

Discussions similaires

  1. [Excel] XLS avec histogramme
    Par ericw78 dans le forum Documents
    Réponses: 4
    Dernier message: 19/03/2013, 15h26
  2. Réponses: 7
    Dernier message: 29/05/2007, 15h11
  3. Fonction template recursive, avec imbrication de types
    Par YéTeeh dans le forum Langage
    Réponses: 5
    Dernier message: 28/04/2006, 17h02
  4. Réponses: 1
    Dernier message: 02/03/2006, 09h52
  5. Création XLS avec histogramme
    Par ericw78 dans le forum Documents
    Réponses: 5
    Dernier message: 07/02/2006, 09h29

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