Mega Code Archive

 
Categories / XML / XSLT StyleSheet
 

For-each-group select=htmlbody group-adjacent

File: Data.xml <?xml version="1.0"?> <html>   <body>     <h2>S</h2>     <p class="item">D <code>key</code> </p>     <p class="item">S</p>     <p class="note">T</p>     <p class="note">M</p>     <p class="note">X</p>     <p class="item">F</p>     <h2>Steps for grouping in XSLT 2.0</h2>     <p class="item">A</p>     <p class="item">B</p>     <p class="note">C</p>     <p class="item">D</p>   </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">               <ul>                 <xsl:for-each select="current-group()">                   <li>                     <xsl:copy-of select="@*[not(name()='class')]"/>                     <xsl:apply-templates select="*|text()"/>                   </li>                 </xsl:for-each>               </ul>             </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>                 <p>                       <xsl:value-of                          select="if (count(current-group()) gt 1)                                 then 'Notes'                                  else 'Note'"/>                 </p>                     <ol start="{$starting-point}">                       <xsl:for-each select="current-group()">                         <li>                           <xsl:copy-of select="@*[not(name()='class')]"/>                           <xsl:apply-templates select="*|text()"/>                         </li>                       </xsl:for-each>                     </ol>              </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: <h2>S</h2> <ul>    <li>D <code>key</code>     </li>    <li>S</li> </ul> <p>Notes</p> <ol start="1">    <li>T</li>    <li>M</li>    <li>X</li> </ol> <ul>    <li>F</li> </ul> <h2>Steps for grouping in XSLT 2.0</h2> <ul>    <li>A</li>    <li>B</li> </ul> <p>Note</p> <ol start="4">    <li>C</li> </ol> <ul>    <li>D</li> </ul>