Reputation: 31
Apologies. I asked a question just a few days ago and it was already answered by Sir michael.hor257k. I have a new requirement though. The TOTAL field needs to count the sgtin fields per unique value like the sample below.
<xsl:template match="/*">
<MESSAGE>
<PALLET>
<xsl:for-each select="//*[local-name()='ObjectEvent'][substring(epcList/epc,1,16) = 'urn:epc:id:sgtin']">
<MATERIAL>
<BOX>
<TOTAL>
<xsl:value-of select="count(./epcList/epc[substring(.,1,16) = 'urn:epc:id:sgtin'])"/>
</TOTAL>
<xsl:for-each select="./epcList/epc[substring(.,1,16) = 'urn:epc:id:sgtin']">
<SERIES>
<ITEM>
<xsl:value-of select="substring-after(substring-after(.,'.'),'.')"/>
</ITEM>
</SERIES>
</BOX>
</MATERIAL>
</PALLET>
</MESSAGE>
This is a sample input file:
<?xml version="1.0" encoding="UTF-8"?>
<n0:EPCISDocument xmlns:n0="urn:epcglobal:epcis:xsd:1" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" schemaVersion="1.1">
<ObjectEvent>
<epcList>
<epc>urn:epc:id:sgtin:999999999.0000.0000000001</epc>
<epc>urn:epc:id:sgtin:999999999.0000.0000000002</epc>
</epcList>
<Extension>
<obj>
<BATCH>ABCD_00</BATCH>
</obj>
</Extension>
</ObjectEvent>
<ObjectEvent>
<epcList>
<epc>urn:epc:id:sgtin:999999999.0000.0000000003</epc>
<epc>urn:epc:id:sgtin:999999999.0000.0000000004</epc>
<epc>urn:epc:id:sgtin:999999999.0000.0000000005</epc>
</epcList>
<Extension>
<obj>
<BATCH>ABCD_00</BATCH>
</obj>
</Extension>
</ObjectEvent>
<ObjectEvent>
<epcList>
<epc>urn:epc:id:sgtin:999999999.1111.0000000006</epc>
<epc>urn:epc:id:sgtin:999999999.1111.0000000007</epc>
<epc>urn:epc:id:sgtin:999999999.1111.0000000008</epc>
</epcList>
<Extension>
<obj>
<BATCH>EFGH_11</BATCH>
</obj>
</Extension>
</ObjectEvent>
<ObjectEvent>
<epcList>
<epc>urn:epc:id:sgtin:999999999.2222.0000000009</epc>
</epcList>
<Extension>
<obj>
<BATCH>IJKL_22</BATCH>
</obj>
</Extension>
</ObjectEvent>
</n0:EPCISDocument>
The TSERIES will be counted per GTIN (0000, 1111, 2222).
The expected should be:
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>
<PALLET>
<MATERIAL>
<BOX>
<TOTAL>5</TOTAL>
<SERIES>
<ITEM>0000000001</ITEM>
</SERIES>
<SERIES>
<ITEM>0000000002</ITEM>
</SERIES>
</BOX>
</MATERIAL>
<MATERIAL>
<BOX>
<TOTAL>5</TOTAL>
<SERIES>
<ITEM>0000000003</ITEM>
</SERIES>
<SERIES>
<ITEM>0000000004</ITEM>
</SERIES>
<SERIES>
<ITEM>0000000005</ITEM>
</SERIES>
</BOX>
</MATERIAL>
<MATERIAL>
<BOX>
<TOTAL>3</TOTAL>
<SERIES>
<ITEM>0000000006</ITEM>
</SERIES>
<SERIES>
<ITEM>0000000007</ITEM>
</SERIES>
<SERIES>
<ITEM>0000000008</ITEM>
</SERIES>
</BOX>
</MATERIAL>
<MATERIAL>
<BOX>
<TOTAL>1</TOTAL>
<SERIES>
<ITEM>0000000009</ITEM>
</SERIES>
</BOX>
</MATERIAL>
</PALLET>
</MESSAGE>
Is this possible Masters?
edit: I'm not sure if this can help. I edited the source payload to add BATCH field. that is unique per GTIN. Can it be used for the TSERIES total?
Upvotes: 0
Views: 63
Reputation: 116982
As I said in the comment, this is a grouping problem and the preferred solution in XSLT 1.0 is to use the Muenchian grouping method:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="batch" match="ObjectEvent" use="Extension/obj/BATCH" />
<xsl:template match="/*">
<MESSAGE>
<PALLET>
<!-- for each distinct batch -->
<xsl:for-each select="ObjectEvent[count(. | key('batch', Extension/obj/BATCH)[1]) = 1]">
<xsl:variable name="current-group" select="key('batch', Extension/obj/BATCH)" />
<xsl:variable name="group-total" select="count($current-group/epcList/epc)"/>
<!-- for each ObjectEvent in this batch -->
<xsl:for-each select="$current-group">
<MATERIAL>
<BOX>
<TOTAL>
<xsl:value-of select="$group-total"/>
</TOTAL>
<xsl:for-each select="epcList/epc">
<SERIES>
<ITEM>
<xsl:value-of select="substring(., 33)"/>
</ITEM>
</SERIES>
</xsl:for-each>
</BOX>
</MATERIAL>
</xsl:for-each>
</xsl:for-each>
</PALLET>
</MESSAGE>
</xsl:template>
</xsl:stylesheet>
Note that this assumes all SGTINs have the same number of characters.
Upvotes: 1