XSLT Req

Here should go questions about transforming XML with XSLT and FOP.
sammy
Posts: 1
Joined: Sat Jul 09, 2005 4:39 pm

XSLT Req

Post by sammy »

Hi

I have a requirement in XSLT, it is a bit lengthy. First of all let me give the source xml and the target output xml after transforming using XSLT and then explain the requirement.

Source XML

<?xml version="1.0" encoding="UTF-8"?>
<EDT20>
<IDOC BEGIN="1">
<EDI_DC40 SEGMENT="1">
<CREDAT>20050708</CREDAT>
</EDI_DC40>
<E1EDT20 SEGMENT="1">
<Z1EDT20 SEGMENT="1">
<ZSHPCNTRY>US</ZSHPCNTRY>
<ZCURCOD>USD</ZCURCOD>
</Z1EDT20>
<Z1EDT20 SEGMENT="1">
<ZSHPCNTRY>US</ZSHPCNTRY>
<ZCURCOD>USD</ZCURCOD>
</Z1EDT20>
<E1EDL20 SEGMENT="1">
<BTGEW>6.200</BTGEW>
<GEWEI>LB</GEWEI>
<ANZPK>00001</ANZPK>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>WE</PARTNER_Q>
<PARTNER_ID>0004100357</PARTNER_ID>
<NAME1>COME CLEAN JANITORIAL</NAME1>
<COUNTRY1>US</COUNTRY1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>OSO</PARTNER_Q>
<PARTNER_ID>0002</PARTNER_ID>
<NAME1>TENNANT</NAME1>
<COUNTRY1>US</COUNTRY1>
</E1ADRM1>
<E1EDL33>
<GRWCU>USD</GRWCU>
</E1EDL33>
<E1EDL47>
<SHIPACCT>560010</SHIPACCT>
<XSISRVC>03</XSISRVC>
<E1EDL48>
<XSIQUALF>BOOK1</XSIQUALF>
<VLABDATA>1234567</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>PAGENR</XSIQUALF>
<VLABDATA>001</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>ZCHARGTYPE</XSIQUALF>
<VLABDATA>PRE</VLABDATA>
</E1EDL48>
</E1EDL47>
<E1EDL37 SEGMENT="1">
<BRGEW>6.200</BRGEW>
<MEABM>INH</MEABM>
<E1EDL49>
<TRACKN>1Z5600100300083710</TRACKN>
</E1EDL49>
</E1EDL37>
</E1EDL20>
<E1EDL20 SEGMENT="1">
<BTGEW>6.200</BTGEW>
<GEWEI>LB</GEWEI>
<ANZPK>00001</ANZPK>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>WE</PARTNER_Q>
<PARTNER_ID>0004100357</PARTNER_ID>
<NAME1>COME CLEAN JANITORIAL</NAME1>
<COUNTRY1>US</COUNTRY1>
</E1ADRM1>
<E1EDL33>
<GRWCU>USD</GRWCU>
</E1EDL33>
<E1EDL47>
<SHIPACCT>560010</SHIPACCT>
<XSISRVC>03</XSISRVC>
<E1EDL48>
<XSIQUALF>BOOK1</XSIQUALF>
<VLABDATA>1234567</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>PAGENR</XSIQUALF>
<VLABDATA>001</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>ZCHARGTYPE</XSIQUALF>
<VLABDATA>PRE</VLABDATA>
</E1EDL48>
</E1EDL47>
<E1EDL37 SEGMENT="1">
<BRGEW>6.200</BRGEW>
<MEABM>INH</MEABM>
<E1EDL49>
<TRACKN>1Z5600100300083710</TRACKN>
</E1EDL49>
</E1EDL37>
</E1EDL20>
<E1EDL20 SEGMENT="1">
<BTGEW>6.200</BTGEW>
<GEWEI>LB</GEWEI>
<ANZPK>00001</ANZPK>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>WE</PARTNER_Q>
<PARTNER_ID>0004100350</PARTNER_ID>
<NAME1>INTERNATIONAL CLEANER</NAME1>
<COUNTRY1>US</COUNTRY1>
</E1ADRM1>
<E1ADRM1 SEGMENT="1">
<PARTNER_Q>ZY</PARTNER_Q>
<PARTNER_ID>UPS</PARTNER_ID>
<NAME1>UNITED PARCEL SERVICES</NAME1>
<COUNTRY1>US</COUNTRY1>
</E1ADRM1>
<E1EDL33>
<GRWCU>USD</GRWCU>
</E1EDL33>
<E1EDL47>
<SHIPACCT>560010</SHIPACCT>
<XSISRVC>02</XSISRVC>
<E1EDL48>
<XSIQUALF>BOOK1</XSIQUALF>
<VLABDATA>1234567</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>PAGENR</XSIQUALF>
<VLABDATA>001</VLABDATA>
</E1EDL48>
<E1EDL48>
<XSIQUALF>ZCHARGTYPE</XSIQUALF>
<VLABDATA>PRE</VLABDATA>
</E1EDL48>
</E1EDL47>
<E1EDL37 SEGMENT="1">
<BRGEW>6.200</BRGEW>
<MEABM>INH</MEABM>
<E1EDL49>
<TRACKN>1Z5600100300083700</TRACKN>
</E1EDL49>
</E1EDL37>
</E1EDL20>
</E1EDT20>
</IDOC>
</EDT20>

XML After Transformation

<?xml version="1.0" encoding="UTF-8"?>
<Ship>
<PickupDate>20050708</PickupDate>
<Ship_BP>
<Identifier>*AA</Identifier>
<SenderShipperNumber>560010</SenderShipperNumber>
<ShipperCountry>US</ShipperCountry>
<BookNum>1234567</BookNum>
<PageNum>001</PageNum>
</Ship_BP>
<Ship_Info>
<Identifier>*BA</Identifier>
<ShipmentNumber>1Z5600100300083710</ShipmentNumber>
<PackageCount>00002</PackageCount>
<ShipmentActualWeight>12.400</ShipmentActualWeight>
<UOMWeight>LB</UOMWeight>
<UPSServiceType>03</UPSServiceType>
<ShipmentChgType>PRE</ShipmentChgType>
<UOMDim>INH</UOMDim>
<CurrencyCode>USD</CurrencyCode>
</Ship_Info>
<Ship_Info>
<Identifier>*BA</Identifier>
<ShipmentNumber>1Z5600100300083700</ShipmentNumber>
<PackageCount>00001</PackageCount>
<ShipmentActualWeight>6.200</ShipmentActualWeight>
<UOMWeight>LB</UOMWeight>
<UPSServiceType>02</UPSServiceType>
<ShipmentChgType>PRE</ShipmentChgType>
<UOMDim>INH</UOMDim>
<CurrencyCode>USD</CurrencyCode>
</Ship_Info>
<Address_Info>
<Identifier>*CA</Identifier>
<AddressQualifier>18</AddressQualifier>
<CompanyName>COME CLEAN JANITORIAL</CompanyName>
<Country>US</Country>
</Address_Info>
<Address_Info>
<Identifier>*CA</Identifier>
<AddressQualifier>18</AddressQualifier>
<CompanyName>INTERNATIONAL CLEANER</CompanyName>
<Country>US</Country>
</Address_Info>
<Address_Info>
<Identifier>*CA</Identifier>
<AddressQualifier>06</AddressQualifier>
<CompanyName>UNITED PARCEL SERVICE</CompanyName>
<Country>US</Country>
</Address_Info>
<Pkg_Info>
<Identifier>*PA</Identifier>
<PackageTrackingNumber>1Z5600100300083710</PackageTrackingNumber>
<PackageActualWeight>6.200</PackageActualWeight>
</Pkg_Info>
<Pkg_Info>
<Identifier>*PA</Identifier>
<PackageTrackingNumber>1Z5600100300083700</PackageTrackingNumber>
<PackageActualWeight>6.200</PackageActualWeight>
</Pkg_Info>
</Ship>

Now let me explain the scenario.
Under <Ship> node PickupDate maps to CREDAT.

Under <ShipBP> node,
Identifier is a constant '*AA'.
SenderShipperNumber will have the value of the first occurence of SHIPACCT, which is in the path /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL47/SHIPACCT.
ShipperCountry maps to first value of ZSHPCNTRY, which is in the path /EDT20/IDOC/E1EDT20/Z1EDT20/ZSHPCNTRY.
BookNum has a small logic associated to it. It is first value of VLABDATA picked up from /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL47/E1EDL48/VLABDATA with the check that XSIQUALF = 'BOOK1'.
PageNum also is similar to BookNum, except that the check is XSIQUALF = 'PAGENR'.

Now comes the next node <Ship_Info>. Identifier is a constant '*BA'. This is a bit complex. We see that the <Ship_Info> node comes thrice. The number of times the node is repeated is based on the following check. We should first identify the PARTNER_Q elements with value of 'WE'. PARTNER_Q is in the path, /EDT20/IDOC/E1EDT20/E1EDL20/E1ADRM1/PARTNER_Q. If the PARTNER_Q value is 'WE', then the value of 'AddressQualifier' would be '18',and also we should check for the PARTNER_ID value. If PARTNER_Q is 'WE' and PARTNER_ID value is the same then, we should basically aggregate the values of ANZPK (path is /EDT20/IDOC/E1EDT20/E1EDL20/ANZPK) for PackageCount, BRGEW (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL37/BRGEW) for ShipmentActualWeight.
In the above example, PARTNER_Q = 'WE' occurs 3 times. But out of the 3 times, the first 2 occurence has the same PARTNER_ID of 0004100357, so we club those 2 as a single occurence, and sum up corresponding ANZPK (00001 + 00001 = 00002) and BRGEW (6.200 + 6.200 = 12.400). Hence PackageCount will be '00002' and ShipmentActualWeight will be 12.400 the first time. Next for PARTNER_Q = 'WE' and PARTNER_ID =
0004100350, as it appears once, we just take the corresponding PackageCount and ShipmentActualWeight (00001 & 6.200 respectively). When PARTNER_Q = 'SP' then the AddressQualifier will have a value of '06'. Anyother PARTNER_Q value should not be considered at all. The other values such as UOMWeight (path is /EDT20/IDOC/E1EDT20/E1EDL20/GEWEI), UPSServiceType (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL47/XSISRVC),UOMDIM (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL37/MEABM), CurrencyCode (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL33/GRWCU). For ShipmentChgType (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL47/E1EDL48/VLABDATA) there is a condition check like XSIQUALF = 'ZCHARGTYPE'.

Next comes the final node <Pkg_Info>, here also the identifier is a constant. In this case this node occurs twice. This is based on PackageTrackingNumber i.e TRACKN (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL37/E1EDL49/TRACKN), if TRACKN is repeated ignore the duplicate, and take the corresponding PackageActualWeight i.e BRGEW (path is /EDT20/IDOC/E1EDT20/E1EDL20/E1EDL37/BRGEW).

I have tried my best to put forward the requirement, in case it is not clear please do ask me. Also remember the nodes are dynamic, so the number of nodes can change as per the source XML. I need a solution preferably in XSLT 1.0, if possible.

thanks
Sammy