'Issue in moving nodes under new node

I am facing an issue rearranging the nodes in given output structure. Company1, Company2, Company 3 is static. These won't change. So I need three of them in SCompany List.

Company4, and Company5 is dynamic in the sense that either one of these or both of these can be present in NCompany List.

I need nodes with text A1, B2, C3 to be formed under SCompany. If A1 is repeated under any node except <Given> <GivenId>, I don't need those.

Maybe I have to use mode?

Input Structure

<root>  
  <Given>
    <GivenId>testchecki</GivenId>
  </Given>
  <Given>
    <GivenId>STOP</GivenId>
    <List>
      <ValueGiven>100000</ValueGiven>
    </List>
  </Given> 
  <Given>
    <GivenId>A1</GivenId>
    <List id="Same">
      <ValueGiven>50000</ValueGiven>
    </List>
    <List id="Different">
      <ValueGiven>200000</ValueGiven>
    </List>
  </Given>
  <Given>
    <GivenId>B2</GivenId>
    <List id="Same">
      <ValueGiven>500001</ValueGiven>
    </List>
    <List id="Different">
      <ValueGiven>3000001</ValueGiven>
    </List>
  </Given>
  <Given>
    <GivenId>C3</GivenId>
    <List id="Same">
      <ValueGiven>500002</ValueGiven>
    </List>
    <List id="Different">
      <ValueGiven>3000002</ValueGiven>
    </List>
  </Given>

  <Given>
    <GivenId>F4</GivenId>
    <Change>EX</Change>
    <List id="Same">
      <ValueGiven>500003</ValueGiven>
    </List>
    <List id="Different">
      <ValueGiven>3000003</ValueGiven>
    </List>
  </Given>
  <Given>
    <GivenId>G5</GivenId>
    <Change>Eptest</Change>
    <List id="Same">
      <ValueGiven>10000004</ValueGiven>
    </List>
    <List id="Different">
      <ValueGiven>2000004</ValueGiven>
    </List>
  </Given>
</root>

Output structure

<root>
  <Scompany>
    <A1>
      <GivenId></GivenId>
      <Same></Same>
      <Different></Different>
    </A1>
    <B2>
      <GivenId></GivenId>
      <Same></Same>
      <Different></Different>
    </B2>
    <C3>
      <GivenId></GivenId>
      <Same></Same>
      <Different></Different>
    </C3>
  </Scompany>
  <Ncompany>
    <F4>
      <GivenId></GivenId>
      <Same></Same>
      <Different></Different>
    </F4>
 </Ncompany>
 <Ncompany>
    <G5>
      <GivenId></GivenId>
      <Same></Same>
      <Different></Different>
    </G5>
  </Ncompany>
</root>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="root/Given">
    <xsl:if test="position()=6 or position()=7">
      <NCompany>
        <xsl:apply-templates mode="check"></xsl:apply-templates>
      </NCompany>
    </xsl:if>
    <xsl:if test="position()=3 or position()=4 or position()=5">
      <xsl:apply-templates mode="test"></xsl:apply-templates>
    </xsl:if>
  </xsl:template>
  <xsl:template match="root/Given" mode="test">


    <xsl:if test="Given/text()='A1'">
      <xsl:element name="{concat(name(), position())}">

        <xsl:copy>
          <xsl:apply-templates select="node()"/>
        </xsl:copy>
      </xsl:element>
    </xsl:if>

    <xsl:if test="Given/text()='B2'">
      <xsl:element name="{concat(name(), position())}">

        <xsl:apply-templates select="node()"/>
      </xsl:element>
    </xsl:if>

    <xsl:if test="Given/text()='C3'">
      <xsl:element name="{concat(name(), position())}">

        <xsl:apply-templates select="node()"/>
      </xsl:element>
    </xsl:if>

  </xsl:template>

  <xsl:template match="root/Given" mode="check">

    <xsl:if test="position()=6 or position()=7">
      <xsl:element name="{concat(name(), position())}">

        <xsl:apply-templates select="node()"/>
      </xsl:element>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>



Solution 1:[1]

This is the basic idea. You'll need to adjust it to satisfy your undocumented requirements.

<xsl:template match="root">
  <xsl:copy>
    <xsl:element name="Scompany">
      <!-- Select the Given nodes that should be in Scompany. Ensure only one Given per GivenId is selected. -->
      <xsl:apply-templates select="Given[GivenId = 'A1'][1]|Given[GivenId = 'B2'][1]|Given[GivenId = 'C3'][1]"/>
    </xsl:element>
    <xsl:element name="Ncompany">
      <!-- Select the given nodes that should be in Ncompany. Ensure only one Given per GivenId is selected.-->
      <xsl:apply-templates select="Given[GivenId = 'F4'][1]|Given[GivenId = 'G5'][1]"/>
    </xsl:element>
  </xsl:copy>
</xsl:template>

<xsl:template match="Given">
  <xsl:element name="{GivenId}">
    <xsl:apply-templates select="node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="GivenId">
  <xsl:copy>
  </xsl:copy>
</xsl:template>

<xsl:template match="List">
  <xsl:choose>
    <xsl:when test="@id='Same'">
      <xsl:element name="Same">
      </xsl:element>
    </xsl:when>    
    <xsl:when test="@id='Different'">
      <xsl:element name="Different">
      </xsl:element>
    </xsl:when>    
  </xsl:choose>
</xsl:template>

<xsl:template match="Change"/>

<!-- This is the bottom -->

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user7333101