Home > Enterprise >  Grouping adjacent elements with different classes
Grouping adjacent elements with different classes

Time:01-28

I want to group elements with @ and with @ into a single .

Input:

<html>
  <head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
      <title>Title</title>
  </head>
  <body>
      <section>
         <h1 >A section</h1>
         <p >Some bodytext.</p>
         <p >1234</p>
         <p >23456</p>
         <p >2341</p>
         <p >Some bodytext.</p>
         <p >Eletrical hazard</p> 
         <p >Do not:</p> 
         <ul >
             <li >
                 <p >Take a bath and</p>
             </li>
             <li >
                 <p >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 >A section</h1>
         <p >Some bodytext.</p>
         <div >
            <p >1234</p>
            <p >23456</p>
            <p >2341</p>
         </div>
         <p >Some bodytext.</p>
         <div >
            <p >Eletrical hazard</p> 
            <p >Do not:</p> 
            <ul >
               <li >
                 <p >Take a bath and</p>
               </li>
               <li >
                 <p >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 >
                                <xsl:apply-templates select="current-group()"/>
                            </div>
                        </xsl:when>
                        <xsl:when test="(current-grouping-key = 'warning') or (current-grouping-key = 'warninglistbullet')">
                            <div >
                                <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:

  • I do not know how to write the boolean pattern to match "parts" and "warning" and "warninglistbullet".
  • If I try to group-by class and evaluate the current-grouping-key() as "warning" OR "warningbulletitem", then the two elements never end up being grouped together.

CodePudding user response:

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