Search code examples
xslt-2.0

XSLT adding tag in specific pattern


I have a issue with adding a "P" tag before next pattern matching .

Source i am getting is:

<root>
<Element>
    <P>Value1</P>
    <P>
        <Level1>
            <Level2 type="i">Name1</Level2>, Title1
        </Level1>, Text1 
        <Level1>
            <Level2 type="i">Name2</Level2>
        </Level1>, Text2.</P>
    <P>
        <Level1>
            <Level2 type="i">Name3</Level2>, Title2
        </Level1>, Text3.
    </P>
</Element>

Desired out i want is

<root>
<Element>
    <P>Value1</P>
    <P>
        <Level1>
            <Level2 type="i">Name1</Level2>, Title1
        </Level1>, Text1 
    </P>
    <P>
        <Level1>
            <Level2 type="i">Name2</Level2>
        </Level1>, Text2.</P>
    <P>
        <Level1>
            <Level2 type="i">Name3</Level2>, Title2
        </Level1>, Text3.
    </P>
</Element>
</root>

The following template does not give me desired result, Please help

<xsl:template match="Element">
    <xsl:copy>
        <xsl:for-each-group select="P" group-starting-with="Level1/Level2">
                <P>
                    <xsl:sequence select="current-group()"/>
                </P>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

Solution

  • I think you need to use the for-each-group on a template matching P and then you get

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    
        <xsl:strip-space elements="*"/>
        <xsl:output indent="yes"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="P">
            <xsl:for-each-group select="node()" group-starting-with="Level1[Level2]">
                    <P>
                        <xsl:apply-templates select="current-group()"/>
                    </P>
            </xsl:for-each-group>  
        </xsl:template>
    
    </xsl:transform>
    

    which at http://xsltransform.net/gVhD8QT gives the result

    <?xml version="1.0" encoding="UTF-8"?>
    <root>
       <Element>
          <P>Value1</P>
          <P>
             <Level1>
                <Level2 type="i">Name1</Level2>, Title1
            </Level1>, Text1 
            </P>
          <P>
             <Level1>
                <Level2 type="i">Name2</Level2>
             </Level1>, Text2.</P>
          <P>
             <Level1>
                <Level2 type="i">Name3</Level2>, Title2
            </Level1>, Text3.
        </P>
       </Element>
    </root>