Diego Schiavon
Diego Schiavon

Reputation: 187

Grouping adjacent elements with different classes

I want to group elements with @class="warning" and with @class="warninglistbullet" into a single .

Input:

<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>Title</title>
  </head>
  <body>
      <section>
         <h1 class="heading1">A section</h1>
         <p class="bodytext">Some bodytext.</p>
         <p class="parts">1234</p>
         <p class="parts">23456</p>
         <p class="parts">2341</p>
         <p class="bodytext">Some bodytext.</p>
         <p class="warning">Eletrical hazard</p> 
         <p class="warning">Do not:</p> 
         <ul class="warninglistbullet">
             <li class="warninglistbullet">
                 <p class="warninglistbullet">Take a bath and</p>
             </li>
             <li class="warninglistbullet">
                 <p class="warninglistbullet">use power tools at the same time.</p>
             </li>
         </ul>
      </section>
   </body>
</html>

Desired output:

<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>Title</title>
  </head>
  <body>
      <section>
         <h1 class="heading1">A section</h1>
         <p class="bodytext">Some bodytext.</p>
         <div class="parts">
            <p class="parts">1234</p>
            <p class="parts">23456</p>
            <p class="parts">2341</p>
         </div>
         <p class="bodytext">Some bodytext.</p>
         <div class="warning">
            <p class="warning">Eletrical hazard</p> 
            <p class="warning">Do not:</p> 
            <ul class="warninglistbullet">
               <li class="warninglistbullet">
                 <p class="warninglistbullet">Take a bath and</p>
               </li>
               <li class="warninglistbullet">
                 <p class="warninglistbullet">use power tools at the same time.</p>
               </li>
            </ul>
         </div>
      </section>
   </body>
</html>

Current, wrong template:

<xsl:template match="section">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@*"/>
            <xsl:for-each-group select="*[@class!='']" group-adjacent="@class">
                    <xsl:choose>
                        <xsl:when test="current-grouping-key = 'parts'">
                            <div class="parts">
                                <xsl:apply-templates select="current-group()"/>
                            </div>
                        </xsl:when>
                        <xsl:when test="(current-grouping-key = 'warning') or (current-grouping-key = 'warninglistbullet')">
                            <div class="warning">
                                <xsl:apply-templates select="current-group()"/>
                            </div>        
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:apply-templates select="current-group()"/>
                        </xsl:otherwise>
                    </xsl:choose>
            </xsl:for-each-group>
        </xsl:element>
    </xsl:template>

I am able to group together elements with the same class, but how to group elements with different classes?

--

Apparently, Stackoverflow will not let me post the question because there is too much code and too little explanation.

So I will ramble on just to please the script that is preventing me from posting.

I tried both the "boolean" pattern and the "@class" pattern in the for-each-group element. I was not able to get either to work:

Upvotes: 0

Views: 36

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

How about:

<xsl:template match="section">
    <xsl:copy>
        <xsl:for-each-group select="*[@class!='']" group-adjacent="replace(@class, 'warninglistbullet', 'warning')">
            <xsl:choose>
                <xsl:when test="current-grouping-key() = ('parts', 'warning')">
                    <div class="{current-grouping-key()}">
                        <xsl:apply-templates select="current-group()"/>
                    </div>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="current-group()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

Upvotes: 1

Related Questions