We use XSLT to map business data from XML to XML and with no web involvement. I need to take XML input and output the same data with certain types of multiply occurring records consolidated into one. What is simple in procedural language has me stumped with XSLT.
I need to process this XML to output this same data with some records aggragated into a single record.
Each G07 represents an E2EDT37 carton and each E2EDT43 below the E2EDT37 is a part and quantity within that carton. The fields that identify the part are E2EDT43_VBELN and E2EDT43_POSNR.
The last G07 has 2 E2EDT42 records that represent the same part with E2EDT43_VBELN=0060088483 and E2EDT43_POSNR=000010. We shipped 178 but get 2 E2EDT43s with quantities of 1 and 177 instead of 1 E2EDT43 with 178.
So I need a template that will go through and create identical output to the input aside from combining the relevant E2EDT43s.
This is the input:
<G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060085134</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>80.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089627903000005</E2EDT43_MATNR> </E2EDT43> </G07> <G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060085134</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>80.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089627903000005</E2EDT43_MATNR> </E2EDT43> </G07> <G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060088483</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>1.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089136322000005</E2EDT43_MATNR> </E2EDT43> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060088483</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>177.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089136322000005</E2EDT43_MATNR> </E2EDT43> </G07> </G01> </ACTIS>
This above needs to become this:
<G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060085134</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>80.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089627903000005</E2EDT43_MATNR> </E2EDT43> </G07> <G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060085134</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>80.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089627903000005</E2EDT43_MATNR> </E2EDT43> </G07> <G07> <E2EDT37> <E2EDT37_SEGNAM>E2EDT37006</E2EDT37_SEGNAM> </E2EDT37> <E2EDT38> <E2EDT38_SEGNAM>E2EDT38000</E2EDT38_SEGNAM> </E2EDT38> <E2EDT43> <E2EDT43_SEGNAM>E2EDT43005</E2EDT43_SEGNAM> <E2EDT43_VELIN>1</E2EDT43_VELIN> <E2EDT43_VBELN>0060088483</E2EDT43_VBELN> <E2EDT43_POSNR>000010</E2EDT43_POSNR> <E2EDT43_VEMNG>178.000</E2EDT43_VEMNG> <E2EDT43_VEMEH>PCE</E2EDT43_VEMEH> <E2EDT43_MATNR>089136322000005</E2EDT43_MATNR> </E2EDT43> </G07> </G01> </ACTIS>
I did have a template that would go through and add elements to certain record types and it workled well. But I was matching on the E2EDT37 record and here I am matching at the G07 which has child records. What I can't grasp is how I would work on the G07 data and combine the like E2EDT43s, write out the new G07 and then resume processing the data after the end of the G07? I lose context and don't know how to resume at the next G07 or whatever record comes next. The data has been simplified here to just the relevant records, but there is much more data after the G07 groups that doesn't need any changes.
This is what was working to add elements to certain records and otherwise repreoduce the input exactly. When the E2EDT37 or E2EDT43 template executed the flow just continued to the next record but matching on the G07 and processing the node with children I can't manage to so that.
<xsl:template match="*" name="segments">
<xsl:choose>
<xsl:when test="name() = 'E2EDT37' ">
<xsl:call-template name="E2EDT37">
<xsl:with-param name="E2EDT37" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:when test="name() = 'E2EDT43' ">
<xsl:call-template name="E2EDT43">
<xsl:with-param name="E2EDT43" select="."/>
</xsl:call-template>
</xsl:when>
<xsl:when test="name(child::*[1]) != ''">
<xsl:element name="{name()}">
<!-- write parent segment -->
<xsl:for-each select="child::*">
<!-- read child segment -->
<xsl:call-template name="segments"/>
</xsl:for-each>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test=".!='' and name()!='rest'">
<xsl:call-template name="create_element"/>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Use the following Powershell Script. You need to use the parent node to get data. I create a parent node Root to get results
Here is XML file
Here is Powershell script
Here is results