XML/XSLT stylesheet/for each group

Материал из Web эксперт
Версия от 11:26, 26 мая 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Alternate group

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <SCENE>

 <TITLE>title 1</TITLE>
 <STAGEDIR>Enter</STAGEDIR>
 <SPEECH>
   <SPEAKER>I</SPEAKER>
   <LINE>A</LINE>
   <LINE>A</LINE>
   <LINE>C</LINE>
   <LINE>B</LINE>
   <LINE>H</LINE>
   <LINE>A</LINE>
 </SPEECH>

</SCENE> File: Transform.xslt <xsl:stylesheet version="2.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    

<xsl:output method="html" indent="yes"/> <xsl:template match="SPEECH">

 <tr>
 <xsl:for-each-group select="*" 
          group-adjacent="if (self::SPEAKER) then 0 else 1">
   <td valign="top">
      <xsl:for-each select="current-group()">
            <xsl:apply-templates select="."/>
         <xsl:if test="position()!=last()">
</xsl:if> </xsl:for-each> </td> </xsl:for-each-group> </tr>

</xsl:template> <xsl:template match="/"> <html>

 <head>
   <title><xsl:value-of select="SCENE/TITLE"/></title>
 </head>
 <body>

<xsl:value-of select="SCENE/TITLE"/>

   <xsl:apply-templates select="SCENE"/>
 </body>

</html> </xsl:template> <xsl:template match="ACT">

<xsl:value-of select="TITLE"/>

 <xsl:apply-templates select="* except TITLE"/>

</xsl:template>

<xsl:template match="SCENE">

<xsl:variable name="sequence" as="element()*"> <xsl:for-each-group select="* except TITLE" group-adjacent="if (self::SPEAKER) then "SPEAKERS" else "LINES""> <xsl:element name="{current-grouping-key()}"> <xsl:copy-of select="current-group()"/> </xsl:element> </xsl:for-each-group> </xsl:variable> <xsl:for-each-group select="$sequence" group-starting-with="SPEAKERS"> <xsl:for-each select="current-group()"> </xsl:for-each> </xsl:for-each-group>
         <xsl:for-each select="*">
           <xsl:apply-templates/>  
           <xsl:if test="position() != last()">
</xsl:if> </xsl:for-each>

</xsl:template> <xsl:template match="STAGEDIR">   <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet> Output: <html>

  <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title>title 1</title>
  </head>
  <body>

title 1

Enter
                  I
                  A
                  A
                  C
                  B
                  H
                  A
                
  </body>

</html>

</source>
   
  


Composite

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <staff>

 <employee name="J" department="sales" />
 <employee name="B" department="personnel" />
 <employee name="C" department="transport" />
 <employee name="W" department="personnel" />
 <employee name="M" department="sales" />

</staff>

File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes" />
 <xsl:template match="staff">
   <xsl:for-each-group select="employee" group-by="@location">
     <xsl:for-each-group select="current-group()"
       group-by="@department">

<xsl:value-of select=""Department:", @department, "Location:", @location" separator=" " />

       <xsl:for-each select="current-group()">
         <xsl:sort select="@name" />

<xsl:value-of select="@name" />

       </xsl:for-each>
     </xsl:for-each-group>
   </xsl:for-each-group>
 </xsl:template>

</xsl:stylesheet>

</source>
   
  


for-each-group select="current-group() except ."

   <source lang="xml">

<?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="body">
   <xsl:copy>
     <xsl:for-each-group select="*" group-starting-with="h1">
       <xsl:apply-templates select="." mode="group" />
     </xsl:for-each-group>
   </xsl:copy>
 </xsl:template>
 <xsl:template match="h1" mode="group">
     <head>
       <xsl:value-of select="." />
     </head>
     <xsl:for-each-group select="current-group() except ."
       group-starting-with="h2">
       <xsl:apply-templates select="." mode="group" />
     </xsl:for-each-group>
 </xsl:template>
 <xsl:template match="h2" mode="group">
     <head>
       <xsl:value-of select="." />
     </head>
     <xsl:for-each-group select="current-group() except ."
       group-starting-with="h3">
       <xsl:apply-templates select="." mode="group" />
     </xsl:for-each-group>
 </xsl:template>
 <xsl:template match="h3" mode="group">
     <head>
       <xsl:value-of select="." />
     </head>
     <xsl:copy-of select="current-group() except ." />
 </xsl:template>
 <xsl:template match="p" mode="group">
   <xsl:copy-of select="current-group()" />
 </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

 A
 B
 C
 D
 E
 F
 G
 H
 I
 J
 K
 L
</source>
   
  


for-each-group select="html/body/*" group-adjacent

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <html>

 <body>

S

D key

S

T

M

X

F

Steps for grouping in XSLT 2.0

A

B

C

D

 </body>

</html>

File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="2.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" include-content-type="no"/>
 <xsl:template match="/">
     <xsl:for-each-group select="html/body/*"
         group-adjacent="if (self::p[@class="item"]) then 1 
                         else if (self::p[@class="note"]) then 2 
                         else 3">
         <xsl:choose>
           <xsl:when test="current-grouping-key() = 1">
    <xsl:for-each select="current-group()">
  • <xsl:copy-of select="@*[not(name()="class")]"/> <xsl:apply-templates select="*|text()"/>
  •                </xsl:for-each>
    
           </xsl:when>
           <xsl:when test="current-grouping-key() = 2">
             <xsl:variable name="starting-point">
               <xsl:number count="p[@class="note"]" level="any" format="1"/>
             </xsl:variable>

<xsl:value-of select="if (count(current-group()) gt 1) then "Notes" else "Note""/>

    <xsl:for-each select="current-group()">
  1. <xsl:copy-of select="@*[not(name()="class")]"/> <xsl:apply-templates select="*|text()"/>
  2.                      </xsl:for-each>
    
           </xsl:when>
           <xsl:otherwise>
             <xsl:for-each select="current-group()">
               <xsl:apply-templates select="."/>
             </xsl:for-each>
           </xsl:otherwise>
         </xsl:choose>
       </xsl:for-each-group>
 </xsl:template>
 <xsl:template match="*">
   <xsl:copy>
     <xsl:copy-of select="@*"/>
     <xsl:apply-templates/>
   </xsl:copy>
 </xsl:template>

</xsl:stylesheet> Output:

S

  • D key
  • S

Notes

  1. T
  2. M
  3. X
  • F

Steps for grouping in XSLT 2.0

  • A
  • B

Note

  1. C
  • D
</source>
   
  


Group by department

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <staff>

 <employee name="J" department="sales" />
 <employee name="B" department="personnel" />
 <employee name="C" department="transport" />
 <employee name="W" department="personnel" />
 <employee name="M" department="sales" />

</staff>

File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes" />
 <xsl:template match="staff">
   <xsl:for-each-group select="employee" group-by="@department">

<xsl:value-of select="current-grouping-key()" /> <xsl:text> department</xsl:text>

     <xsl:for-each select="current-group()">

<xsl:value-of select="@name" />

     </xsl:for-each>
   </xsl:for-each-group>
 </xsl:template>

</xsl:stylesheet> Output:

sales department

J

M

personnel department

B

W

transport department

C

</source>
   
  


Multi-level

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <staff>

 <employee name="J" department="sales" location="New York" />
 <employee name="B" department="personnel" location="Los Angeles" />
 <employee name="C" department="transport" location="New York" />
 <employee name="W" department="personnel" location="Los Angeles" />
 <employee name="M" department="sales" location="Seattle" />

</staff>

File: Transform.xslt

<?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes" />
 <xsl:template match="staff">
   <xsl:for-each-group select="employee" group-by="@location">
     <xsl:sort select="current-grouping-key()" />

<xsl:text>Location </xsl:text> <xsl:value-of select="current-grouping-key()" />

     <xsl:for-each-group select="current-group()"
       group-by="@department">
       <xsl:sort select="current-grouping-key()" />

<xsl:text>Location </xsl:text> <xsl:value-of select="current-grouping-key()" />

       <xsl:for-each select="current-group()">
         <xsl:sort select="@name" />

<xsl:text>Location </xsl:text> <xsl:value-of select="@name" />

       </xsl:for-each>
     </xsl:for-each-group>
   </xsl:for-each-group>
 </xsl:template>

</xsl:stylesheet> Output:

Location Los Angeles

Location personnel

Location B

Location W

Location New York

Location sales

Location J

Location transport

Location C

Location Seattle

Location sales

Location M

</source>
   
  


Sort by department

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <staff>

 <employee name="J" department="sales" />
 <employee name="B" department="personnel" />
 <employee name="C" department="transport" />
 <employee name="W" department="personnel" />
 <employee name="M" department="sales" />

</staff> File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes" />
 <xsl:template match="staff">
   <xsl:for-each-group select="employee" group-by="@department">
     <xsl:sort select="current-grouping-key()" />

<xsl:value-of select="current-grouping-key()" /> <xsl:text> department</xsl:text>

     <xsl:for-each select="current-group()">
       <xsl:sort select="@name" />

<xsl:value-of select="@name" />

     </xsl:for-each>
   </xsl:for-each-group>
 </xsl:template>

</xsl:stylesheet> Output:

personnel department

B

W

sales department

J

M

transport department

C

</source>
   
  


use for-each-group

   <source lang="xml">

File: Data.xml <?xml version="1.0"?> <towns>

 <town>A</town>
 <town>B</town>
 <town>C</town>
 <town>D</town>
 <town>E</town>
 <town>F</town>
 <town>G</town>
 <town>H</town>
 <town>I</town>
 <town>J</town>
 <town>K</town>
 <town>L</town>

</towns>

File: Transform.xslt <?xml version="1.0"?> <xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:param name="cols" select="4" />
 <xsl:template match="towns">
<xsl:for-each-group select="town" group-adjacent="(position()-1) idiv $cols"> <xsl:for-each select="current-group()"> </xsl:for-each> </xsl:for-each-group>
             <xsl:value-of select="." />
 </xsl:template>

</xsl:stylesheet> Output: <?xml version="1.0" encoding="UTF-8"?>

A B C D
E F G H
I J K L
</source>