element. If

following-sibling[1] is element and

va" /> element. If

following-sibling[1] is element and

va" /> element. If

following-sibling[1] is element and

va"/>

How can grouping `block` element inside in '<p class="p">' element?

74 views Asked by At

I want to grouping <block> element in inside the <p class="p"> element. If <p class="p"> following-sibling[1] is <block> element and <p class="p1"> value inside in <p class="p"> element.
Input XML File-:

<root>
    <p class="p">aaaaaa</p>
    <block>
        <p>block</p>
    </block>
    <p class="p1"> bbb </p>
    <block>
        <p>block</p>
    </block>
    <p class="p1">bbb.</p>
    <p class="p">cccc</p>
</root>

I want to expected output below.
Output XML file:

<root>
    <p class="p">aaaaaa<block><p>block</p></block> bbb <block><p>block</p></block>bbb.</p>
    <p class="p">cccc</p>
</root>

Can we right the logic another way to above the output, I am using XSLT below above the output:

<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    
    <xsl:template match="p[@class='p']">
        <xsl:choose>
            <xsl:when test="following-sibling::*[1][self::block]">
                <xsl:text disable-output-escaping="yes">&lt;p&gt;</xsl:text>
                <xsl:apply-templates/>
            </xsl:when>
            <xsl:otherwise>
                <p><xsl:apply-templates select="@*|node()"/></p>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template match="p[@class='p1']">
        <xsl:choose>
            <xsl:when test="following-sibling::*[1][self::p[@class='p']]">
                <xsl:apply-templates/>
                <xsl:text disable-output-escaping="yes">&lt;/p&gt;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
1

There are 1 answers

3
Martin Honnen On BEST ANSWER

The following seems to wrap/group the right nodes for the input sample but I am not sure it implements your requirements, I haven't quite understood them.

  <xsl:template match="root">
    <xsl:copy>
      <xsl:for-each-group select="*" group-starting-with="p[@class = 'p']">
        <xsl:copy>
          <xsl:apply-templates select="node(), current-group() except ."/>
        </xsl:copy>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>