【问题标题】:how to apply group by on xslt elements如何在 xslt 元素上应用 group by
【发布时间】:2011-01-09 22:31:53
【问题描述】:

我需要根据某个属性对值进行分组并填充它。

下面提到的是 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>

预期结果: 我需要根据 Division 对值进行分组并填充,即

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

【问题讨论】:

    标签: xslt grouping


    【解决方案1】:

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

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

    【讨论】:

    • 如果可以的话,我会给这个+10,很好的例子:-)
    • 在 XSLT 2.0 示例中,如果不使用 key() 函数, 的用途是什么?
    • @Paul,声明密钥没有任何目的,我在没有它的情况下测试了代码。它看起来像是 XSLT 1.0 版本的剩余部分,作者在将其修改为 2.0 版本时忘记删除它。我删除了声明并修复了拼写错误 Users -> User 和 Division 属性的选择。
    【解决方案2】:

    使用

    <xsl:for-each-group  select="*"
    group-by="@Division"> 
    ....
    </xsl:for-each-group> 
    

    看看这个例子:http://www.zvon.org/xxl/XSL-Ref/Tutorials/For-Each-Group/feg1.html

    【讨论】:

      【解决方案3】:

      我不喜欢添加这样的元素,这就是我要做的。这完美地工作。它提供了您需要的输出。试试看。

      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>
      

      【讨论】:

      • XSLT 2 需要key 吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多