cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

weird structure to map

Former Member
0 Likes
1,512

Hello.

Currently I'm facing a weird structure to map, source is a well defined xml data object but target structure is weirdly de-coupled and I'm not sure how to solve it via message mapping. I was asked to avoid java mapping usage, so I have to try to make it work with message mapping.

Source structure is something like this:

As you can see is a normal well defined xml data object with two header fields acting like a primary key.

Target structure would be:

It is like it was defined as relational tables where struct acts as a header table and substruct is another table referencing struct by the composite primary key. Items are like registries in the tables. I know is weird but it is the requirement.

I have tried several combinations of functions remove context, use one as many and split by value but none of them seems to get the desired result.

Thanks in advance for any help the community can offer.

Accepted Solutions (1)

Accepted Solutions (1)

former_member190293
Active Contributor

Hi Juan!

Something like this (just template):

Regards, Evgeniy.

Former Member

Evgeniy you are the man of the day. You nailed it!

The trick was to change the context of substructure to use the root context, not the parent. You won't believe me but I was thinking about toying with this next in my tests.

It works like a charm. I did several tests duplicating the structures and substructures a random number of times and the target document was build correctly without missing any information.

Answers (3)

Answers (3)

Former Member

By the way, I even tried going deeper by adding another substructure to the substructure, something like sub_substructure and you can map the keys correctly as long as you change the substructure ans sub_substructure context to the root and generating enough contexts in the graphical mapping, something like this:

Context change:

Generating enough contexts:

JaySchwendemann
Active Contributor

If XSL is not an option, this should be doable with usaOneAsMany and some context magic. Admitedly UOAM is one of the most user-unfriendly functions there is, and every time I need it I refrain from doing so, as I need to get my head around it once more.

That being said, have a look at https://integrationlearn.com/sap-pi-mapping/useoneasmany-explained-in-easy-example/ (this was once a blog within SDN but I can't for the live of me find it within SAP community. I hope it was mutually agreed to move outside and it was not simply nicked 😉

This should quite well match your requirement? The biggest difference I see is that you are having sub-structures while the tutorial doesn't.

Also look at this: https://blogs.sap.com/2015/02/20/useoneasmany-in-sap-pi/

Cheers

Jens

Former Member
0 Likes

Great links!

I'll bookmark them.

Thank you very much Jens.

JaySchwendemann
Active Contributor

I mostly dealt with such requirments using XSLT Mappings. Particularly have a look at apply-templates. Should be doable by the looks of the source and the target

  • XML
<?xml version="1.0"?>
<ns0:updateShpmntByIDReq xmlns:ns0="http://example.org/name1">
	<Shipment>
		<ShipID>0815</ShipID>
		<Deliveries>
			<Delivery>
				<DeliveryID>5312000684</DeliveryID>
				<SAPCarrierID>0000998450</SAPCarrierID>
				<CarrierName>Dingsbums</CarrierName>
				<LocationID>12345</LocationID>
				<ActualWeight>239.55</ActualWeight>
				<WeightUnit>kg</WeightUnit>
				<TotalCharge>3021.23</TotalCharge>
				<LSTTotalCharge>10021.44</LSTTotalCharge>
				<Currency>USD</Currency>
				<HandlingUnits>
					<HandlingUnit>
						<HandlingUnitID>0010881741</HandlingUnitID>
						<TrackingNumber>1234</TrackingNumber>
						<TotalCharge>13.45</TotalCharge>
						<ListTotalCharge>33.21</ListTotalCharge>
						<Status>SHPD</Status>
						<TimeStamp>2013-03-21T12:04:09</TimeStamp>
						<ActualWeight>0.23</ActualWeight>
						<WeightUnit>kg</WeightUnit>
					</HandlingUnit>
					<HandlingUnit>
						<HandlingUnitID>0010881742</HandlingUnitID>
						<TrackingNumber>1235</TrackingNumber>
						<TotalCharge>14.45</TotalCharge>
						<ListTotalCharge>34.21</ListTotalCharge>
						<Status>SHPD</Status>
						<TimeStamp>2013-03-21T12:04:10</TimeStamp>
						<ActualWeight>0.24</ActualWeight>
						<WeightUnit>kg</WeightUnit>
					</HandlingUnit>
					<HandlingUnit>
						<HandlingUnitID>0010881743</HandlingUnitID>
						<TrackingNumber>1236</TrackingNumber>
						<TotalCharge>15.45</TotalCharge>
						<ListTotalCharge>35.21</ListTotalCharge>
						<Status>SHPD</Status>
						<TimeStamp>2013-03-21T12:04:11</TimeStamp>
						<ActualWeight>0.25</ActualWeight>
						<WeightUnit>kg</WeightUnit>
					</HandlingUnit>
				</HandlingUnits>
			</Delivery>
		</Deliveries>
	</Shipment>
</ns0:updateShpmntByIDReq>


  • XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://example.org/name1">
	<xsl:template match="/ns0:updateShpmntByIDReq/Shipment/Deliveries/Delivery/HandlingUnits/HandlingUnit">
		<handlingUnitHeader>
			<shipmentExtKey>
				<xsl:value-of select="/ns0:updateShpmntByIDReq/Shipment/ShipID"/>
			</shipmentExtKey>
			<sequentialNo/>
			<processingStatus/>
			<delKey>
				<xsl:value-of select="parent::*/parent::*/DeliveryID"/>
			</delKey>
			<handlingUnitExtKey>
				<xsl:value-of select="./HandlingUnitID"/>
			</handlingUnitExtKey>
			<trackingNo>
				<xsl:value-of select="./TrackingNumber"/>
			</trackingNo>
			<statusHeader>
				<xsl:value-of select="./Status"/>
			</statusHeader>
			<timeStamp>
				<xsl:value-of select="./TimeStamp"/>
			</timeStamp>
			<totalWeight>
				<xsl:value-of select="./ActualWeight"/>
			</totalWeight>
			<totalWeightUnit>
				<xsl:value-of select="./WeightUnit"/>
			</totalWeightUnit>
		</handlingUnitHeader>
	</xsl:template>
	<xsl:template match="/ns0:updateShpmntByIDReq/Shipment/Deliveries/Delivery">
		<deliveryHeader>
			<shipmentExtKey>
				<xsl:value-of select="/ns0:updateShpmntByIDReq/Shipment/ShipID"/>
			</shipmentExtKey>
			<sequentialNo/>
			<processingStatus/>
			<delKey>
				<xsl:value-of select="./DeliveryID"/>
			</delKey>
			<carrierKey>
				<xsl:value-of select="./SAPCarrierID"/>
			</carrierKey>
			<carrierName>
				<xsl:value-of select="./CarrierName"/>
			</carrierName>
			<shippingPoint>
				<xsl:value-of select="./LocationID"/>
			</shippingPoint>
			<totalWeight>
				<xsl:value-of select="./ActualWeight"/>
			</totalWeight>
			<totalWeightUnit>
				<xsl:value-of select="./WeightUnit"/>
			</totalWeightUnit>
			<totalChargeListPrice>
				<xsl:value-of select="./LSTTotalCharge"/>
			</totalChargeListPrice>
			<totalCharge>
				<xsl:value-of select="./TotalCharge"/>
			</totalCharge>
			<totalChargeCurrency>
				<xsl:value-of select="./Currency"/>
			</totalChargeCurrency>
		</deliveryHeader>
	</xsl:template>
	<xsl:template match="/">
		<ns1:updateShpmntByIDReq xmlns:ns1="http://example.org/name2">
			<shipment>
				<shipmentExtKey>
					<xsl:value-of select="/ns0:updateShpmntByIDReq/Shipment/ShipID"/>
				</shipmentExtKey>
				<processingStatus/>
			</shipment>
			<xsl:apply-templates select="/ns0:updateShpmntByIDReq/Shipment/Deliveries/Delivery"/>
			<xsl:apply-templates select="/ns0:updateShpmntByIDReq/Shipment/Deliveries/Delivery/HandlingUnits/HandlingUnit"/>
		</ns1:updateShpmntByIDReq>
	</xsl:template>
</xsl:stylesheet>

This might be solvable via graphical mapping, though. Maybe someone else wants to chime in for that

PS: Forgive the lenghty code but the community software didn't allow for zip, and had some problems when I changed extenstions of the files to .txt either.

Former Member
0 Likes

Hi Jens.

Unfortunately XSL is also out of the question. But it is a nice approach and I'll give a try when client and me give up on graphical mapping.

Thanks.