xslt-2.0xslt-3.0

XSLT: Checking the length and copying the value


I am trying to write an XSLT to check if <identification>, which has <identificationType> as Type10 or not, if it exist and <identificationValue> length is less than or equal to 5 then Identificationvalue we need to replace with <serialShippingContainerCode>, if identificationType=Type10 not exist then we need to create one with identificationvalue taking from Serialshippingcontainercode.

XSLT i have used is only copying header to child if it not exist, Please assist here once

Input:

<StandardBusinessDocument>
    <receivingAdvice>
        <LogisticUnitLineItem>
            <logisticUnitIdentification>
                <ContainerCode>
                    <serialShippingContainerCode>121212345890</serialShippingContainerCode>
                </ContainerCode>
            </logisticUnitIdentification>
            <ContainmentLine number="1">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>Value1</IdentificationValue>
                        <IdentificationType>Type8</IdentificationType>
                    </Identification>
                    <Identification>
                        <IdentificationValue>4567</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
            <ContainmentLine number="2">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>Value2</IdentificationValue>
                        <IdentificationType>Type8</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
        </LogisticUnitLineItem>
        <LogisticUnitLineItem>
            <logisticUnitIdentification>
                <ContainerCode>
                    <serialShippingContainerCode>1309089485</serialShippingContainerCode>
                </ContainerCode>
            </logisticUnitIdentification>
            <ContainmentLine number="1">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>86432509</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
            <ContainmentLine number="2">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>6867</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
        </LogisticUnitLineItem>
    </receivingAdvice>
</StandardBusinessDocument>

** Desired Output:**

<StandardBusinessDocument>
    <receivingAdvice>
        <LogisticUnitLineItem>
            <logisticUnitIdentification>
                <ContainerCode>
                    <serialShippingContainerCode>121212345890</serialShippingContainerCode>
                </ContainerCode>
            </logisticUnitIdentification>
            <ContainmentLine number="1">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>Value1</IdentificationValue>
                        <IdentificationType>Type8</IdentificationType>
                    </Identification>
                    <Identification>
                        <IdentificationValue>121212345890</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
            <ContainmentLine number="2">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>Value2</IdentificationValue>
                        <IdentificationType>Type8</IdentificationType>
                    </Identification>
                    <Identification>
                        <IdentificationValue>121212345890</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
        </LogisticUnitLineItem>
        <LogisticUnitLineItem>
            <logisticUnitIdentification>
                <ContainerCode>
                    <serialShippingContainerCode>1309089485</serialShippingContainerCode>
                </ContainerCode>
            </logisticUnitIdentification>
            <ContainmentLine number="1">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>86432509</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
            <ContainmentLine number="2">
                <containedItemIdentification>
                    <gtin>00000000000000</gtin>
                    <Identification>
                        <IdentificationValue>1309089485</IdentificationValue>
                        <IdentificationType>Type10</IdentificationType>
                    </Identification>
                </containedItemIdentification>
            </ContainmentLine>
        </LogisticUnitLineItem>
    </receivingAdvice>
</StandardBusinessDocument>

** XSLT I used is below:**

<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(IdentificationType, 'Type10'))]">
    <xsl:copy-of select="."/>
    <xsl:copy>
      <IdentificationValue>
        <xsl:value-of select="ancestor::LogisticUnitLineItem/logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/>
      </IdentificationValue>
      <IdentificationType>Type10</IdentificationType>
    </xsl:copy>
  </xsl:template> 
  
</xsl:stylesheet>

Solution

  • You can do it with two templates.

    The first searches for Identification and replaces the IdentificationValue appropriatelly.

    The other searches for the parent node containedItemIdentification and then appends adds the Identification to it.

    So see my proposal below. I don't explain it more, because it is quite simple if you are a bit in XSLT. Learning and thinking in XSLT in my opinion is one of the hardest things. But stay tuned! :-) After a while you get a better feeling how to address real problems.

    <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">
        <xsl:copy>
          <xsl:choose>
            <xsl:when test="IdentificationType='Type10' and string-length(IdentificationValue) &lt; 5">
              <IdentificationValue>
                <xsl:value-of select="../../../logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/>
              </IdentificationValue>
              <xsl:apply-templates select="IdentificationType"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="@*|node()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="containedItemIdentification">
       <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
          <xsl:if test="not(Identification/IdentificationType[.='Type10'])">
            <Identification>
              <IdentificationValue>
                <xsl:value-of select="../../logisticUnitIdentification/ContainerCode/serialShippingContainerCode"/>
              </IdentificationValue>
              <IdentificationType>Type10</IdentificationType>
            </Identification>
         </xsl:if>    
        </xsl:copy>
      </xsl:template>
    </xsl:stylesheet>