'Form multiple parent node for each of its descendants

Im quite new to xslt and breaking my head over this issue. Can anyone please help me with this? Please find the input XML, I need to look for text L1 in id field of L node and search sublocation id and pit ref has text L1 and form new L1 node and arrange sublocation and pit under each L1 nodes.

<root>
  <L Id="L1">
    <test>ed</test>
    <SubLocation id="L1S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SubLocation>
    <SubLocation id="L1S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SubLocation>
  </L>
  <L Id="L2">
    <test>ed</test>
    <SubLocation id="L2S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SubLocation>
    <SubLocation id="L2S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SubLocation>
  </L>
  <cp>
    <current>
      <Amt>20154.00</Amt>
    </current>
    <pi>
      <pit ref="L1S1">
        <value>1232</value>
      </pit>
      <pit ref="L1S2">
        <value>12345</value>
      </pit>
      <pit ref="L1S3">
        <value>12387</value>
      </pit>
      <pit ref="L2S1">
        <value>1232</value>
      </pit>
      <pit ref="L2S2">
        <value>12345</value>
      </pit>
    </pi>
  </cp>
</root>

I need the o/p in following format

<root>
  <L1>
    <SubLocation id="L1S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SubLocation>
    <pit ref="L1S1">
      <value>1232</value>
    </pit>
  </L1>
  <L1>
    <SubLocation id="L1S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SubLocation>
    <pit ref="L1S2">
      <value>12345</value>
    </pit>
  </L1>
  <L2>
    <SubLocation id="L2S1">
      <check>
        <AId>1</AId>
      </check>
      <MD>
        <UnitNumber>1</UnitNumber>
      </MD>
    </SubLocation>
    <pit ref="L2S1">
      <value>1232</value>
    </pit>
  </L2>
  <L2>
    <SubLocation id="L2S2">
      <check>
        <AId>2</AId>
      </check>
      <MD>
        <UnitNumber>2</UnitNumber>
      </MD>
    </SubLocation>
    <pit ref="L2S2">
      <value>12345</value>
    </pit>
  </L2>
</root>

This is my xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:key name="cpbyid" match="pit" use="@ref"/>
  <xsl:key name="slById" match="SubLocation" use="@id"/>
  <xsl:key name="locbyId" match="L" use="@id"/>

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

  <xsl:template match="L/*[@id]">
    <L>
      <xsl:value-of select="//L/@id"/>
    <pifo>
      <xsl:call-template name="subloc"></xsl:call-template>    
      <xsl:call-template name="identity"/>
    </pifo>
    </L>
  </xsl:template>


  <xsl:template match="pit/*[@ref]" name="subloc">
    <inf>
      <xsl:copy-of select="key('cpbyid', @id)"/>
      <xsl:copy-of select="key('slById', @id)"/>
    </inf>
  </xsl:template> 

</xsl:stylesheet>


Solution 1:[1]

I don't follow your description that well and I may be missing something. Is there a reason why you cannot do simply:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="pit" match="pit" use="@ref" />

<xsl:template match="/root">
    <xsl:copy>
        <xsl:for-each select="L/SubLocation">
             <xsl:element name="{../@Id}">
                <xsl:copy-of select="."/>
                <xsl:copy-of select="key('pit', @id)"/>
              </xsl:element>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

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