web-dev-qa-db-ja.com

xslt要素にgroup byを適用する方法

何らかの属性に基づいて値をグループ化し、値を設定する必要があります。

以下はi/p xmlであり、Usersとid 2,4の4つの行がある場合、Divisionは同じです。つまり、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>
34
Amit

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>
84
Lachlan Roche

使用する

<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

2
Pentium10

私はそのような要素を追加することを好みません、そして、これは私がすることです。これは完全に機能します。必要な出力が得られます。やってみよう。

[〜#〜] 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.

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

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

どちらかを使用すると、これが得られますoutput

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