2010-01-27 6 views
30

Je dois regrouper la valeur en fonction de certains attributs et la peupler.comment appliquer un groupe sur des éléments xslt

mentionné ci-dessous est i/p xml et si vous voyez il y a 4 lignes pour les utilisateurs et pour id 2,4 Division est le même à savoir HR

tout en générant o/p réelle que je dois groupe par la Division .. . De l'aide ???

I/P XML

<Users> 
<User id="2" name="ABC" Division="HR"/> 
<User id="3" name="xyz" Division="Admin"/> 
<User id="4" name="LMN" Division="Payroll"/> 
<User id="5" name="PQR" Division="HR"/> 
</Users> 

Résultat attendu: J'ai besoin de regrouper les valeurs basées sur la division et POPULATE-à-dire

<AllUsers> 
<Division value="HR"> 
    <User> 
    <id>2</id> 
    <name>ABC</name> 
    </User> 
    <User> 
    <id>5</id> 
    <name>PQR</name> 
    </User> 
</Division> 
<Division value="ADMIN"> 
    <User> 
    <id>3</id> 
    <name>XYZ</name> 
    </User> 
</Division> 
<Division value="Payroll"> 
    <User> 
    <id>4</id> 
    <name>LMN</name> 
    </User> 
</Division> 
</AllUsers> 

Répondre

74

En XSLT 1.0, en utilisant le groupement Muenchian.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes" /> 

    <xsl:key name="division" match="User" use="@Division" /> 

    <xsl:template match="Users"> 
     <AllUsers> 
      <xsl:apply-templates select="User[generate-id(.)=generate-id(key('division',@Division)[1])]"/> 
     </AllUsers> 
    </xsl:template> 

    <xsl:template match="User"> 
     <Division value="{@Division}"> 
      <xsl:for-each select="key('division', @Division)"> 
       <User> 
        <id><xsl:value-of select="@id" /></id> 
        <name><xsl:value-of select="@name" /></name> 
       </User> 
      </xsl:for-each> 
     </Division> 
    </xsl:template> 

</xsl:stylesheet> 

Dans XSLT 2.0, utilisez xsl: foreach groupe

<xsl:output method="xml" indent="yes" /> 

<xsl:template match="Users"> 
    <AllUsers> 
     <xsl:for-each-group select="User" group-by="@Division"> 
      <Division value="{@Division}"> 
       <xsl:for-each select="current-group()"> 
        <User> 
         <id><xsl:value-of select="@id" /></id> 
         <name><xsl:value-of select="@name" /></name> 
        </User> 
       </xsl:for-each> 
      </Division> 
     </xsl:for-each-group> 
    </AllUsers> 
</xsl:template> 

+0

+1, celui-ci vient de me sauvé de maux de tête :) – Damb

+0

Je donnerais ce 10 si je pouvais, grand exemple :-) – raffian

+1

Dans l'exemple XSLT 2.0, quel est le but de si vous n'utilisez pas la fonction key()? – Paul

0

Je ne préférais pas d'ajouter des éléments comme ça et ce que je vais faire. Cela fonctionne parfaitement. Il donne la sortie dont vous avez besoin. Essaye le.

XML

<?xml version="1.0"?> 
<Users> 
<User id="2" name="ABC" Division="HR"/> 
<User id="3" name="xyz" Division="Admin"/> 
<User id="4" name="LMN" Division="Payroll"/> 
<User id="5" name="PQR" Division="HR"/> 
</Users> 

XSLT 1,0

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" indent="yes" /> 
    <xsl:key name="division" match="User" use="@Division" /> 
    <xsl:template match="Users"> 
     <xsl:element name="AllUsers"> 
     <xsl:apply-templates select="User[generate-id(.)=generate-id(key('division',@Division)[1])]" /> 
     </xsl:element> 
    </xsl:template> 
    <xsl:template match="User"> 
     <xsl:element name="Division"> 
     <xsl:attribute name="value"> 
      <xsl:value-of select="@Division" /> 
     </xsl:attribute> 
     <xsl:for-each select="key('division', @Division)"> 
      <xsl:element name="User"> 
       <xsl:element name="id"> 
        <xsl:value-of select="@id" /> 
       </xsl:element> 
       <xsl:element name="name"> 
        <xsl:value-of select="@name" /> 
       </xsl:element> 
      </xsl:element> 
     </xsl:for-each> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

XSLT 2,0

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes" /> 
    <xsl:key name="division" match="User" use="@Division" /> 
    <xsl:template match="Users"> 
     <xsl:element name="AllUsers"> 
     <xsl:for-each-group select="*" group-by="@Division"> 
      <xsl:element name="Division"> 
       <xsl:attribute name="value"> 
        <xsl:value-of select="@Division" /> 
       </xsl:attribute> 
       <xsl:for-each select="current-group()"> 
        <xsl:element name="User"> 
        <xsl:element name="id"> 
         <xsl:value-of select="@id" /> 
        </xsl:element> 
        <xsl:element name="name"> 
         <xsl:value-of select="@name" /> 
        </xsl:element> 
        </xsl:element> 
       </xsl:for-each> 
      </xsl:element> 
     </xsl:for-each-group> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

En utilisant soit vous donnera cette sortie,

<AllUsers> 
    <Division value="HR"> 
     <User> 
     <id>2</id> 
     <name>ABC</name> 
     </User> 
     <User> 
     <id>5</id> 
     <name>PQR</name> 
     </User> 
    </Division> 
    <Division value="Admin"> 
     <User> 
     <id>3</id> 
     <name>xyz</name> 
     </User> 
    </Division> 
    <Division value="Payroll"> 
     <User> 
     <id>4</id> 
     <name>LMN</name> 
     </User> 
    </Division> 
</AllUsers> 
Questions connexes