user3292620
user3292620

Reputation: 3

dynamic xml nodes using xslt

I use a transformation in SAP in order to generate an XML file. I've already achieved that by referring only to explicit nodes. Now, the requirement would be to enhance the existing XML result by adding new nodes dynamically, based on a number of tags that can vary in number. Here is the XML source :

<!-- edited with XMLSpy v2011 rel. 3 sp1 (http://www.altova.com)-->
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
    <asx:values>
        <MSAPO01>
            <LOGICALID>SAP-AMG</LOGICALID>
            <COMPONENT>Whatever</COMPONENT>
            <CONFIRMATION>Always</CONFIRMATION>
            <CREATIONDATE/>
            <BOID/>
            <SYNC_CONFIRM>Never</SYNC_CONFIRM>
            <SYNC_ACTION>Change</SYNC_ACTION>
            <DATAAREA>
                <item>
                    <ACTION>Change</ACTION>
                    <STATUS_HEAD>Z00</STATUS_HEAD>
                    <CREATIONDATE/>
                    <VBELN>0050023362</VBELN>
                    <POSNR>000001</POSNR>
                    <SHIPTO>C001991</SHIPTO>
                    <QUALITY>C</QUALITY>
                    <MTSMTO>MTO</MTSMTO>
                    <INTEXP>IN</INTEXP>
                    <NTGEW>22.520 </NTGEW>
                    <GEWEI>TO</GEWEI>
                    <DELIVERYMODE>Librex</DELIVERYMODE>
                    <PROPERTIES>
                        <ZPEL_PROPERTY_S>
                            <ID>ACTION</ID>
                            <DESCRIPTION>Action code</DESCRIPTION>
                            <DATAVALUE>007</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>002</ANY>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>AUGRU</ID>
                            <DESCRIPTION>Order reason (reason for the business transaction)</DESCRIPTION>
                            <DATAVALUE>01</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY/>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>ZTERM</ID>
                            <DESCRIPTION>Terms of payment key</DESCRIPTION>
                            <DATAVALUE>0401</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY/>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>QUALF</ID>
                            <DESCRIPTION>IDOC qualifier reference document</DESCRIPTION>
                            <DATAVALUE>001</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>Z022</ANY>
                        </ZPEL_PROPERTY_S>
                        <ZPEL_PROPERTY_S>
                            <ID>QUALF</ID>
                            <DESCRIPTION>IDOC qualifier reference document</DESCRIPTION>
                            <DATAVALUE>002</DATAVALUE>
                            <DATATYPE>CHAR</DATATYPE>
                            <UM/>
                            <ANY>Z023</ANY>
                        </ZPEL_PROPERTY_S>
                    </PROPERTIES>
                </item>
            </DATAAREA>
        </MSAPO01>
    </asx:values>
</asx:abap>

The 'Properties' node is dynamically determined (in numbers and content). My original XSLT is:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.siemens.com/ad/mes/b2mt-1.0" xmlns:amg="Pelican@AMG" xmlns:bml="http://www.wbf.org/xml/b2mml-v02" xmlns:oag="http://www.openapplications.org/oagis"
xmlns:sit="http://www.siemens.com/ad/mes/b2mml-v02-SITExt-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://www.siemens.com/ad/mes/b2mt-1.0 C:\DATA_EXCHANGE\B2MT\B2MT_Schemas\AMG_ProductionSchedule.xsd">
  <xsl:template match="MSAPO01">
    <SyncProductionSchedule>
      <oag:ApplicationArea>
        <oag:Sender>
          <oag:LogicalId>
            <xsl:value-of select="LOGICALID"/>
          </oag:LogicalId>
          <oag:Component>
            <xsl:value-of select="COMPONENT"/>
          </oag:Component>
          <oag:Confirmation>
            <xsl:value-of select="CONFIRMATION"/>
          </oag:Confirmation>
        </oag:Sender>
        <oag:CreationDateTime>
          <xsl:value-of select="CREATIONDATE"/>
        </oag:CreationDateTime>
        <oag:BODId>
          <xsl:text>0000000000017092</xsl:text>
        </oag:BODId>
      </oag:ApplicationArea>
      <DataArea>
        <xsl:comment> WorkOrder  </xsl:comment>
        <oag:Sync>
          <xsl:attribute name="confirm">
            <xsl:value-of select="SYNC_CONFIRM"/>
          </xsl:attribute>
          <oag:SyncCriteria>
            <oag:SyncExpression>
              <xsl:attribute name="action">
                <xsl:value-of select="SYNC_ACTION"/>
              </xsl:attribute>
            </oag:SyncExpression>
          </oag:SyncCriteria>
        </oag:Sync>
        <xsl:apply-templates select="DATAAREA"/>
      </DataArea>
    </SyncProductionSchedule>
  </xsl:template>
  <xsl:template match="DATAAREA">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="DATAAREA/item">
    <bml:ProductionSchedule>
      <bml:ID>
        <xsl:text>Default</xsl:text>
      </bml:ID>
      <bml:ProductionRequest>
        <bml:ID>
          <xsl:value-of select="concat(VBELN,'/',POSNR)"/>
        </bml:ID>
        <bml:Any>
          <sit:ProductionRequestExtension>
            <sit:Quantity>
              <bml:QuantityString>
                <xsl:value-of select="NTGEW"/>
              </bml:QuantityString>
              <bml:DataType>
                <xsl:text>float</xsl:text>
              </bml:DataType>
              <bml:UnitOfMeasure>
                <xsl:value-of select="GEWEI"/>
              </bml:UnitOfMeasure>
            </sit:Quantity>
            <sit:ProducedQuantity>
              <xsl:value-of select="PROD_QTY"/>
            </sit:ProducedQuantity>
          </sit:ProductionRequestExtension>
          <amg:ProductionRequestExtension>
            <amg:SAPOrder>
              <amg:SAPOrderID>
                <xsl:value-of select="VBELN"/>
              </amg:SAPOrderID>
              <amg:SAPOrderItem>
                <xsl:value-of select="POSNR"/>
              </amg:SAPOrderItem>
              <amg:SAPStatusHead>
                <xsl:value-of select="STATUS_HEAD"/>
              </amg:SAPStatusHead>              
              <amg:SoldTo>
                <xsl:value-of select="SOLDTO"/>
              </amg:SoldTo>
              <amg:SoldToName>
                <xsl:value-of select="NAME_SOLDTO"/>
              </amg:SoldToName>
              <amg:ShipTo>
                <xsl:value-of select="SHIPTO"/>
              </amg:ShipTo>             
              <amg:Quality>
                <xsl:value-of select="QUALITY"/>
              </amg:Quality>
              <amg:DistributionChannel>
                <xsl:value-of select="INTEXP"/>
              </amg:DistributionChannel>
              <amg:DeliveryMode>
                <xsl:value-of select="DELIVERYMODE"/>
              </amg:DeliveryMode>
            </amg:SAPOrder>
          </amg:ProductionRequestExtension>
        </bml:Any>
      </bml:ProductionRequest>
    </bml:ProductionSchedule>
  </xsl:template>
</xsl:transform>

please help me with the dynamic part in XSLT file in order to get the following output, regardless of the number of properties. The XML output should look like this:

<?xml version="1.0" encoding="utf-8"?>
<!-- edited with XMLSpy v2011 rel. 3 sp1 (http://www.altova.com) -->
<SyncProductionSchedule xmlns="http://www.siemens.com/ad/mes/b2mt-1.0" xmlns:amg="Pelican@ArcelorMittalGalati" xmlns:bml="http://www.wbf.org/xml/b2mml-v02" xmlns:oag="http://www.openapplications.org/oagis" xmlns:sit="http://www.siemens.com/ad/mes/b2mml-v02-SITExt-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <oag:ApplicationArea>
        <oag:Sender>
            <oag:LogicalId>SAP-AMG</oag:LogicalId>
            <oag:Component>Whatever</oag:Component>
            <oag:Confirmation>Always</oag:Confirmation>
        </oag:Sender>
        <oag:CreationDateTime>2014-02-10T12:52:32</oag:CreationDateTime>
        <oag:BODId>0000000000017092</oag:BODId>
    </oag:ApplicationArea>
    <DataArea>
        <!-- WorkOrder  -->
        <oag:Sync confirm="Never">
            <oag:SyncCriteria>
                <oag:SyncExpression action="Change"/>
            </oag:SyncCriteria>
        </oag:Sync>
        <bml:ProductionSchedule>
            <bml:ID>Default</bml:ID>
            <bml:ProductionRequest>
                <bml:ID>0050023362/000001</bml:ID>
                <bml:Any>
                    <sit:ProductionRequestExtension>
                        <sit:Quantity>
                            <bml:QuantityString>22.520 </bml:QuantityString>
                            <bml:DataType>float</bml:DataType>
                            <bml:UnitOfMeasure>TO</bml:UnitOfMeasure>
                        </sit:Quantity>
                        <sit:ProducedQuantity>0.000 </sit:ProducedQuantity>
                    </sit:ProductionRequestExtension>
                    <amg:ProductionRequestExtension>
                        <amg:SAPOrder>
                            <amg:SAPOrderID>0050023362</amg:SAPOrderID>
                            <amg:SAPOrderItem>000001</amg:SAPOrderItem>
                            <amg:SAPStatusHead>Z00</amg:SAPStatusHead>
                            <amg:SoldTo>C001991</amg:SoldTo>
                            <amg:Quality>C</amg:Quality>
                            <amg:DistributionChannel>IN</amg:DistributionChannel>
                            <amg:DeliveryMode>Librex</amg:DeliveryMode>
                            <!-- New Node - OrderProperty -> Begin  -->
                            <amg:SAPOrderProperties>
                                <amg:OrderProperty>
                                    <amg:ID>ACTION</amg:ID>
                                    <amg:Description>Action code</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>007</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>002</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>AUGRU</amg:ID>
                                    <amg:Description>Order reason (reason for the business transaction)</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>01</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any/>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>ZTERM</amg:ID>
                                    <amg:Description>Terms of payment key</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>0401</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any/>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>QUALF</amg:ID>
                                    <amg:Description>IDOC qualifier reference document</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>001</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>Z022</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                                <amg:OrderProperty>
                                    <amg:ID>QUALF</amg:ID>
                                    <amg:Description>IDOC qualifier reference document</amg:Description>
                                    <amg:Value>
                                        <amg:ValueString>001</amg:ValueString>
                                        <amg:DataType>CHAR</amg:DataType>
                                        <amg:UnitOfMeasure>n/a</amg:UnitOfMeasure>
                                        <amg:Any>Z023</amg:Any>
                                    </amg:Value>
                                </amg:OrderProperty>
                            </amg:SAPOrderProperties>
                            <!-- New Node - OrderProperty -> End -->
                        </amg:SAPOrder>
                    </amg:ProductionRequestExtension>
                </bml:Any>
            </bml:ProductionRequest>
        </bml:ProductionSchedule>
    </DataArea>
</SyncProductionSchedule>

Upvotes: 0

Views: 1163

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122414

This seems to be a straightforward extension of your existing stylesheet, you just need to add templates for PROPERTIES and ZPEL_PROPERTY_S

<xsl:template match="PROPERTIES">
  <amg:SAPOrderProperties>
    <xsl:apply-templates select="ZPEL_PROPERTY_S"/>
  </amg:SAPOrderProperties>
</xsl:template>

<xsl:template match="ZPEL_PROPERTY_S">
  <amg:OrderProperty>
    <amg:ID><xsl:value-of select="ID" /></amg:ID>
    <!-- etc. -->
  </amg:OrderProperty>
</xsl:template>

and apply these templates at the appropriate place

          <amg:DeliveryMode>
            <xsl:value-of select="DELIVERYMODE"/>
          </amg:DeliveryMode>
          <xsl:apply-templates select="PROPERTIES" />
        </amg:SAPOrder>

Upvotes: 0

Related Questions