Jason
Jason

Reputation: 45

XSLT Grouping's : Add parent to set of elements in child elements

Using for-each-group I'm trying to add parent node by the class value of each para element. I tried to apply the grouping but the result is not good, I'm not getting the desired output. I'm confused about using the grouping in this case. Is there any better approach in this case for adding the parent node?

Current XML:

<?xml version="1.0" encoding="utf-8" ?>
<section>
  <h1>Some heading</h1>
  <section>
   <p>normal paragaraph</p>
   <p class="list">list 1</p>
   <p class="list">list 1</p>
  
    <p>normal paragaraph</p>
   <p class="list">list 2</p>
   <p class="list">list 2</p>
  </section>
    <section> ...  </section>
</section>

XSLT used:

   <xsl:template match="section">
      <xsl:for-each-group select="node()" group-by="if (@class='list') then 'list' else 'nolist'">
        <xsl:for-each select="current-grouping-key()">
            <xsl:choose>
              <xsl:when test="current-grouping-key() = 'list'">
              <list>
                  <xsl:apply-templates select="current-group()" />
              </list>                
              </xsl:when>
              <xsl:otherwise>
                  <xsl:apply-templates select="current-group()" />
              </xsl:otherwise>
            </xsl:choose>

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

Current Output:


<h1>Some heading</h1>
<p>normal paragaraph</p>
<p>normal paragaraph</p>
<list>
   <p class="list">list 1</p>
   <p class="list">list 1</p>
   <p class="list">list 2</p>
   <p class="list">list 2</p>
</list>

<p>normal paragaraph</p>
....

Expected Output:

<section>
  <h1>Some heading</h1>
  <section>
   <p>normal paragaraph</p>
   <list>
      <p class="list">list 1</p>
      <p class="list">list 1</p>
   </list>
    <p>normal paragaraph</p>
   <list>
      <p class="list">list 2</p>
      <p class="list">list 2</p>
   </list>
</section>
<section>...</section>
</section>

Upvotes: 0

Views: 183

Answers (2)

Otabek Khamdamov
Otabek Khamdamov

Reputation: 46

<xsl:template match="section">
  <section>
    <h1>Some Heading</h1>
    <section>
        <xsl:for-each-group select="section/p" group-by=".">
            <xsl:choose>
              <xsl:when test="current-grouping-key() != 'normal paragaraph'">
                <p>normal paragaraph</p>
                <list>
                  <xsl:for-each select="current-group()">
                      <p class="list"><xsl:value-of select="current-grouping-key()"/></p>
                  </xsl:for-each>
                </list>
              </xsl:when>
            </xsl:choose>
        </xsl:for-each-group>
      </section>
  </section>
</xsl:template>

Upvotes: 2

Jason
Jason

Reputation: 45

Here is the answer I hope this helps someone, as commented by @marthin honnen, I tried with group-adjacent, got the desired output, this helped.

 <xsl:template match="section">
     <xsl:copy>
      <xsl:for-each-group select="*" group-adjacent="if (@class='list') then 'list' else 'nolist'">
        <xsl:for-each select="current-grouping-key()">
            <xsl:choose>
              <xsl:when test="current-grouping-key() = 'list'">
              <list>
                  <xsl:apply-templates select="current-group()" />
              </list>                
              </xsl:when>
              <xsl:otherwise>
                  <xsl:apply-templates select="current-group()" />
              </xsl:otherwise>
            </xsl:choose>

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

Upvotes: 0

Related Questions