Search code examples
xmlxsltxslt-2.0

Need to arrange the topic elements properly using XSLT


I Need to re-arrange the topic element by using the XSL.

Input XML

<?xml version="1.0" encoding="UTF-8"?>
<Body>
    <h1>Children</h1>
    <p>
    <img src="https://tneb.com/Services/Gets/Contents/ucr-images-v1/Images/cup-36" />This is pain in the stomach or belly.</p>
    <h2>Causes</h2>
    <p>When you put a load balancer</p>
    <h3>Found</h3>
    <p>balancer</p>
    <h4>Height</h4>
    <p>stomach</p>
</Body>

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="#all">

  <xsl:template match="Body">     
    <xsl:for-each-group select="*" group-starting-with="h1">
      <topic>
        <xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute>
        <title>
          <xsl:apply-templates select="node()"/>
        </title>
        <xsl:for-each-group select="current-group() except ." group-starting-with="h2">
          <topic>
            <xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute>
            <title>
              <xsl:apply-templates select="node()"/>
            </title>

            <xsl:for-each-group select="current-group() except ." group-starting-with="h3">
              <xsl:choose>
                <xsl:when test="self::h3">
                  <topic>
                    <xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute>
                    <title>
                      <xsl:apply-templates select="node()"/>
                    </title>

                    <xsl:for-each-group select="current-group() except ." group-starting-with="h4">
                      <xsl:choose>
                        <xsl:when test="self::h4">
                          <topic>
                            <xsl:attribute name="id">topic_<xsl:number count="h1 | h2 | h3 | h4"/></xsl:attribute>
                            <title>
                              <xsl:apply-templates select="node()"/>
                            </title>
                            <body><xsl:apply-templates select="current-group() except ."/></body>
                          </topic>
                        </xsl:when>
                        <xsl:otherwise>
                          <body><xsl:apply-templates select="current-group()"/></body>
                        </xsl:otherwise>
                      </xsl:choose>

                    </xsl:for-each-group>
                  </topic>                      
                </xsl:when>
                <xsl:otherwise>
                  <body><xsl:apply-templates select="current-group()"/></body>
                </xsl:otherwise>
              </xsl:choose>

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

  <xsl:template match="img">
    <xsl:element name="image">
      <xsl:attribute name="id">
        <xsl:value-of select="@imageid"/>
      </xsl:attribute>
      <xsl:attribute name="alt">
        <xsl:value-of select="@alt"/>
      </xsl:attribute>
      <xsl:attribute name="height">
        <xsl:value-of select="@height"/>
      </xsl:attribute>
      <xsl:attribute name="width">
        <xsl:value-of select="@width"/>
      </xsl:attribute>
      <xsl:attribute name="align">
        <xsl:value-of select="@class"/>
      </xsl:attribute>
      <xsl:attribute name="href">
        <xsl:value-of select="tokenize(@src, '/')[position() gt last() - 3]" separator="/"/>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>

    <xsl:template match="p">
    <p><xsl:apply-templates/></p>
  </xsl:template>

  </xsl:stylesheet>

Output

<topic id="topic_1">
    <title>Children</title>
    <topic id="topic_">
        <title>
            <image id="47"
     alt="cup."
     height="300"
     width="400"
     align="right"
     href="https://tneb.com/Services/Gets/Contents/ucr-images-v1/Images/cup-36"/>
        This is pain in the stomach or belly.</title>
    </topic>
    <topic id="topic_2">
        <title>Causes</title>
        <p>When you put a load balancer</p>
    </topic>
    <topic id="topic_3">
        <title>Found</title>
        <p>balancer</p>
    </topic>
    <topic id="topic_4">
        <title>Height</title>
        <p>stomach</p>
    </topic>
</topic>

Expected Output

<topic id="topic_1">
    <title>Children</title>
    <body>
        <image id="47"
     alt="cup."
     height="300"
     width="400"
     align="right"
     href="/ucr-images-v1/Images/cup-36"/>
        <p>This is pain in the stomach or belly.</p>
    </body>
    <topic id="topic_2">
        <title>Causes</title>
        <p>When you put a load balancer</p>
    </topic>
    <topic id="topic_3">
        <title>Found</title>
        <p>balancer</p>
    </topic>
    <topic id="topic_4">
        <title>Height</title>
        <p>stomach</p>
    </topic>
</topic>

I need to remove the topic of which that came without the Id number and I need the <body> element instead of that <topic> one as like above.


Solution

  • you have to add same condition like h3 in h2 also

    <xsl:choose>
    <xsl:when test="self::h2">
         ..........
    <xsl:otherwise>
        <body><xsl:apply-templates select="current-group()"/></body>
    </xsl:otherwise>
    </xsl:choose>