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 :

Hiérarchisation d'un XML via transformation XSL (2)


Sujet :

XSL/XSLT/XPATH XML

  1. #1
    Membre à l'essai
    Hiérarchisation d'un XML via transformation XSL (2)
    Bonjour,
    Suite à mon thread précédent, j'ai essayé d'appliquer la solution proposée par tsuji mais je n'arrive pas à l'étendre à des hiérarchisations complémentaires.
    Voici donc un exemple plus complet de ce que je souhaite faire :

    Transformer ce XML "plat" :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <Employees>
    	<Employee> <ID>1</ID> <WeekID>1</WeekID> <DayID>1</DayID> <Hours>5</Hours> </Employee>
    	<Employee> <ID>1</ID> <WeekID>1</WeekID> <DayID>1</DayID> <Hours>4</Hours> </Employee>
    	<Employee> <ID>1</ID> <WeekID>1</WeekID> <DayID>2</DayID> <Hours>7</Hours> </Employee>
    	<Employee> <ID>1</ID> <WeekID>2</WeekID> <DayID>1</DayID> <Hours>5</Hours> </Employee>
    	<Employee> <ID>1</ID> <WeekID>2</WeekID> <DayID>3</DayID> <Hours>8</Hours> </Employee>
    	<Employee> <ID>2</ID> <WeekID>1</WeekID> <DayID>1</DayID> <Hours>5</Hours> </Employee>
    	<Employee> <ID>2</ID> <WeekID>2</WeekID> <DayID>4</DayID> <Hours>4</Hours> </Employee>
    </Employees>


    En :
    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
    <Employees>
    	<Employee>
    		<ID>1</ID>
    		<Weeks>
    			<Week>
    				<WeekID>1</WeekID>
    				<Days>
    					<Day>
    						<DayID>1</DayID>
    						<Hours>5</Hours>
    						<Hours>4</Hours>
    					</Day>
    					<Day>
    						<DayID>2</DayID>
    						<Hours>7</Hours>
    					</Day>
    				</Days>
    			</Week>
    			<Week>
    				<WeekID>2</WeekID>
    				<Days>
    					<Day>
    						<DayID>1</DayID>
    						<Hours>5</Hours>
    					</Day>
    					<Day>
    						<DayID>3</DayID>
    						<Hours>8</Hours>
    					</Day>
    				</Days>
    			</Week>
    		</Weeks>
    	</Employee>
    	<Employee>
    		<ID>2</ID>
    		<Weeks>
    			<Week>
    				<WeekID>1</WeekID>
    				<Days>
    					<Day>
    						<DayID>1</DayID>
    						<Hours>5</Hours>
    					</Day>
    				</Days>
    			</Week>
    			<Week>
    				<WeekID>2</WeekID>
    				<Days>
    					<Day>
    						<DayID>4</DayID>
    						<Hours>4</Hours>
    					</Day>
    				</Days>
    			</Week>
    		</Weeks>
    	</Employee>
    </Employees>


    Quelle serait la transformation XSL à appliquer ? (petite précision qui a son importance : je ne peux pas appliquer le XSLT 2.0, il me faut trouver une solution en XSLT 1.0...)

    Merci d'avance,
    Flophie

  2. #2
    Membre à l'essai
    J'ai trouvé une solution très moche :

    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
    <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="yes"/>
     
    <xsl:template match="/Employees">
    <Employees>
    <xsl:for-each select="Employee">
    <xsl:variable name="EmployeeID" select="ID" />
    <xsl:if test="not(preceding-sibling::Employee[ID=$EmployeeID])">
    <Employee>
    <ID><xsl:value-of select="$EmployeeID"/></ID>
    <Weeks>
     
    <xsl:for-each select="../Employee[ID=$EmployeeID]">
    <xsl:variable name="WeekID" select="WeekID" />
    <xsl:if test="not(preceding-sibling::Employee[ID=$EmployeeID and WeekID=$WeekID])">
    <Week>
    <WeekID><xsl:value-of select="$WeekID"/>
    </WeekID>
    <Days>
     
    <xsl:for-each select="../Employee[ID=$EmployeeID and WeekID=$WeekID]">
    <xsl:variable name="DayID" select="DayID" />
    <xsl:if test="not(preceding-sibling::Employee[ID=$EmployeeID and WeekID=$WeekID and DayID=$DayID])">
    <Day>
    <DayID><xsl:value-of select="$DayID"/></DayID>
     
    <xsl:for-each select="../Employee[ID=$EmployeeID and WeekID=$WeekID and DayID=$DayID]">
    <xsl:variable name="Hours" select="Hours" />
    <xsl:if test="not(preceding-sibling::Employee[ID=$EmployeeID and WeekID=$WeekID and DayID=$DayID and Hours=$Hours])">
    <Hours><xsl:value-of select="Hours"/></Hours>
    </xsl:if>
    </xsl:for-each>
     
    </Day>
    </xsl:if>
    </xsl:for-each>
     
    </Days>
    </Week>
    </xsl:if> 
    </xsl:for-each>
     
    </Weeks>
    </Employee>
    </xsl:if>         
    </xsl:for-each>
    </Employees>
    </xsl:template>
     
    </xsl:stylesheet>


    Si quelqu'un connait la méthode Muenchian et peut m'indiquer comment y transposer ce XSLT, je suis preneur

  3. #3
    Membre émérite
    Si vous vouley ...
    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
    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
    <xsl:stylesheet version="1.0" xmlnssl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes" />
    <xsl:param name="sep" select="'|'" />
    
    <xsl:key name="id-g" match="Employee" use="ID" />
    <xsl:key name="id-wid-g" match="Employee" use="concat(ID, $sep, WeekID)" />
    <xsl:key name="id-wid-did-g" match="Employee" use="concat(ID, $sep, WeekID, $sep, DayID)" />
     
    <xsl:template match="Employees">
        <xsl:copy>
            <xsl:apply-templates select="Employee" />
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Employee[generate-id()=generate-id(key('id-g',ID)[1])]">
        <xsl:variable name="id" select="ID" />
        <xsl:copy>
            <ID><xsl:value-of select="$id" /></ID>
            <Weeks>
                <xsl:for-each select="/Employees/Employee[ID=$id]/WeekID">
                    <xsl:apply-templates select="." />
                </xsl:for-each>
            </Weeks>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="WeekID[generate-id(parent::Employee)=generate-id(key('id-wid-g',concat(preceding-sibling::ID,$sep,.))[1])]">
        <xsl:variable name="id" select="preceding-sibling::ID" />
        <xsl:variable name="wid" select="." />
        <Week>
            <WeekID><xsl:value-of select="$wid" /></WeekID>
            <Days>
                <xsl:for-each select="/Employees/Employee[ID=$id and WeekID=$wid]/DayID">
                    <xsl:apply-templates select="." />
                </xsl:for-each>
            </Days>
        </Week>
    </xsl:template>
    
    <xsl:template match="DayID[generate-id(parent::Employee)=generate-id(key('id-wid-did-g',concat(preceding-sibling::ID,$sep,preceding-sibling::WeekID,$sep,.))[1])]">
        <xsl:variable name="id" select="preceding-sibling::ID" />
        <xsl:variable name="wid" select="preceding-sibling::WeekID" />
        <xsl:variable name="did" select="." />
        <Day>
            <DayID><xsl:value-of select="$did" /></DayID>
            <xsl:for-each select="/Employees/Employee[ID=$id and WeekID=$wid and DayID=$did]/Hours">
                <Hours><xsl:value-of select="." /></Hours>
            </xsl:for-each>
        </Day>
    </xsl:template>
    
    <xsl:template match="Employee" />
    <xsl:template match="WeekID" />
    <xsl:template match="DayID" />
    
    </xsl:stylesheet>

###raw>template_hook.ano_emploi###