2010-01-27 68 views
30

我需要組基於一些屬性值和填充它。如何通過XSLT元素應用組

下面提到是I/P xml和如果看到有4行爲用戶和ID 2,4司是相同即HR

而產生實際O/P我需要組由司.. 。任何幫助?

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> 

預期的結果: 我需要組基於司值和填充即

<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> 

回答

74

在XSLT 1.0,使用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> 

在XSLT 2.0,使用XSL:的foreach組

<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,這個剛剛救了我頭痛:) – Damb 2012-02-23 11:57:46

+0

如果我能我想給這個+10,很好的例子:-) – raffian 2012-09-27 19:11:21

+1

在XSLT 2.0例子,目的是什麼如果你不使用key()函數? – Paul 2013-10-23 17:11:50

0

我不喜歡加入這樣的元素,這是我會做什麼。這工作完美。它提供了你需要的輸出。試試看。

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> 

無論使用會給你這個輸出

<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>