xslt-2.0xslt-3.0

XSLT to Copy header node value to child segment if that segment is not exist


i am trying to write XSLT mapping for copying parent value to child nodes, ContainerCode -- > Serialshippingcontianercode value we need to pass to its subnodes under new tag <identification>, but if that tag already exist then no need to copy that segment, as some other value is exist under it. my existing XSLT is copying the containercode value to all segments.Please help me on this..

i attached sample input and output as below. Please check.

Input:

<StandardBusinessDocument>
  <receivingAdvice>
    <LogisticUnitLineItem>
      <logisticUnitIdentification>
        <ContainerCode>
          <serialShippingContainerCode>ContainerCode123</serialShippingContainerCode>
        </ContainerCode>
      </logisticUnitIdentification>
      <ContainmentLine number="1">
        <containedItemIdentification>
          <gtin>00000000000000</gtin>
          
                 <Identification>
                  <IdentificationValue>ContainerCode456</IdentificationValue>
                  <IdentificationType>PAL</IdentificationType>
               </Identification>
        </containedItemIdentification>
      </ContainmentLine>
      <ContainmentLine number="2">
        <containedItemIdentification>
          <gtin>00000000000000</gtin>
          <Identification>
            <IdentificationValue>Value1</IdentificationValue>
            <IdentificationType>New1</IdentificationType>
          </Identification>
       
        </containedItemIdentification>
      </ContainmentLine>
    </LogisticUnitLineItem>
    <LogisticUnitLineItem>
      <logisticUnitIdentification>
        <ContainerCode>
          <serialShippingContainerCode>ContainerCode2nd</serialShippingContainerCode>
        </ContainerCode>
      </logisticUnitIdentification>
      <ContainmentLine number="1">
        <containedItemIdentification>
          <gtin>00000000000000</gtin>
          <Identification>
            <IdentificationValue>686</IdentificationValue>
            <IdentificationType>SUPP</IdentificationType>
          </Identification>
    
        </containedItemIdentification>
      </ContainmentLine>
    </LogisticUnitLineItem>
  </receivingAdvice>
</StandardBusinessDocument>

** Desired Output:**

<StandardBusinessDocument>
   <receivingAdvice>
      <LogisticUnitLineItem>
         <logisticUnitIdentification>
            <ContainerCode>
               <serialShippingContainerCode>ContainerCode123</serialShippingContainerCode>
            </ContainerCode>
         </logisticUnitIdentification>
         <ContainmentLine number="1">
            <containedItemIdentification>
               <gtin>00000000000000</gtin>
             
                  <IdentificationValue>ContainerCode456</IdentificationValue>
                  <IdentificationType>PAL</IdentificationType>
               </Identification>
            </containedItemIdentification>
         </ContainmentLine>
         <ContainmentLine number="2">
            <containedItemIdentification>
               <gtin>00000000000000</gtin>
               <Identification>
                  <IdentificationValue>Value1</IdentificationValue>
                  <IdentificationType>New1</IdentificationType>
               </Identification>
          
               <Identification>
                  <IdentificationValue>ContainerCode123</IdentificationValue>
                  <IdentificationType>PAL</IdentificationType>
               </Identification>
            </containedItemIdentification>
         </ContainmentLine>
      </LogisticUnitLineItem>
      <LogisticUnitLineItem>
         <logisticUnitIdentification>
            <ContainerCode>
               <serialShippingContainerCode>ContainerCode2nd</serialShippingContainerCode>
            </ContainerCode>
         </logisticUnitIdentification>
         <ContainmentLine number="1">
            <containedItemIdentification>
               <gtin>00000000000000</gtin>
               <Identification>
                  <IdentificationValue>686</IdentificationValue>
                  <IdentificationType>SUPP</IdentificationType>
               </Identification>
             
               <Identification>
                  <IdentificationValue>ContainerCode2nd</IdentificationValue>
                  <IdentificationType>PAL</IdentificationType>
               </Identification>
            </containedItemIdentification>
         </ContainmentLine>
      </LogisticUnitLineItem>
   </receivingAdvice>
</StandardBusinessDocument>

** XSLT I used is below:**

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <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="LogisticUnitLineItem">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
       
        <xsl:with-param name="serialShippingContainerCode" select="logisticUnitIdentification/ContainerCode/serialShippingContainerCode/text()" tunnel="yes"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template> 
  
 
  <xsl:template match="Identification[last()]">
    <xsl:param name="serialShippingContainerCode" tunnel="yes"/>
    <!-- Copy just the current node -->
    <xsl:copy-of select="."/>
    <xsl:copy>
      <IdentificationValue>
        <xsl:value-of select="$serialShippingContainerCode"/>
      </IdentificationValue>
      <IdentificationType>PAL</IdentificationType>
    </xsl:copy>
  </xsl:template> 
  
</xsl:stylesheet>

Solution

  • It is not clear what the exact condition is but if you only want to copy the header value to the last Identification if it doesn't contain a value with ContainerCode then use e.g.

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <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="Identification[last()][not(contains(IdentificationValue, 'ContainerCode'))]">
        <xsl:copy-of select="."/>
        <xsl:copy>
          <IdentificationValue>
            <xsl:value-of select="ancestor::LogisticUnitLineItem/logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/>
          </IdentificationValue>
          <IdentificationType>PAL</IdentificationType>
        </xsl:copy>
      </xsl:template> 
      
    </xsl:stylesheet>