Moving elements of one XML node to a child node using xslt

Viewed 42

Basically I need to move the contents of OrderRelease and Order into the OrderLine level ussing xsl.

Example input XML:

<OrderRelease EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1">
    <Order OrderDate="2019-06-13T09:27:36-04:00" Action="CANCEL" OrderNo="1234ABC">
        <Extn ExtnWMSOrderNumber="123ADS"/>
    </Order>    
    <OrderLines>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="5">
            <Item ItemID="A" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="" PrimeLineNo="2" SubLineNo="1" OrderedQty="10">
            <Item ItemID="B" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="CANCEL" PrimeLineNo="3" SubLineNo="1" OrderedQty="0">
            <Item ItemID="C" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
    </OrderLines>
</OrderRelease>

Example of XML post translation:

<OrderLines>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="5" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1" AggregatorOrderId=”12345 >
            <Item ItemID="A" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="" PrimeLineNo="1" SubLineNo="1" OrderedQty="10" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1" AggregatorOrderId=”12345>
            <Item ItemID="B" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
        <OrderLine Action="CANCEL" PrimeLineNo="1" SubLineNo="1" OrderedQty="0" OrderDate="2019-06-13T09:27:36-04:00" OrderNo="1234ABC" EnterpriseCode="BRD" ReleaseNo="1234ABC" DocumentType="0001" SellerOrganizationCode="BU1" ShipNode="US1 AggregatorOrderId=”12345">
            <Item ItemID="C" UnitOfMeasure="STD" ProductClass="NEW"/>
        </OrderLine>
    </OrderLines>

I used the following XSL but it removes all of the original OrderLine elements and also doesn't seem to do it for each OrderLine

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="OrderRelease">
        <OrderLine>
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
        </OrderLine>
    </xsl:template>

    <xsl:template match="Order">
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
    </xsl:template>
    <xsl:template match="Extn">
            <xsl:copy-of select="@*|OrderLine/@*" />
            <xsl:apply-templates /><!-- optional -->
    </xsl:template>
        <xsl:template match="OrderLine">
            <xsl:copy-of select="@*|OrderLine/@*" />
    </xsl:template>
    
    
</xsl:stylesheet>

Output of this is

<OrderLine EnterpriseCode="BRD"
           ReleaseNo="1234ABC"
           DocumentType="0001"
           SellerOrganizationCode="BU1"
           ShipNode="US1"
           OrderDate="2019-06-13T09:27:36-04:00"
           Action="CANCEL"
           OrderNo="1234ABC"
           ExtnWMSOrderNumber="123ADS"
           PrimeLineNo="3"
           SubLineNo="1"
           OrderedQty="0"/>
1 Answers

You could do it this way.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="OrderLines">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="OrderLine">
    <xsl:copy>
      <xsl:copy-of select="@*"/> <!-- OrderLine attributes -->
      <xsl:copy-of select="../../@*"/> <!-- OrderRelease attributes -->
      <xsl:copy-of select="../../Order/@*"/> <!-- Order attributes -->
      <xsl:attribute name="AggregatorOrderId">12345</xsl:attribute>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="Item">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

See it working here : https://xsltfiddle.liberty-development.net/93nwMog

Related