0

The TOTAL field needs to count ALL ITEM fields for ALL segments. Not just the ITEM fields inside the same segment

I've already tried changing the context by adding another ./ in the beginning of the xpath.

<xsl:template match="nm:EPCISDocument">
  <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>
  </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>
  </ObjectEvent>
</n0:EPCISDocument>

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>
  </PALLET>
</MESSAGE>

But right now based on the code, I'm getting this:

<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>
  <PALLET>
    <MATERIAL>
      <BOX>
        <TOTAL>2</TOTAL>
        <SERIES>
          <ITEM>0000000001</ITEM>
        </SERIES>
        <SERIES>
          <ITEM>0000000002</ITEM>
        </SERIES>
      </BOX>
    </MATERIAL>
    <MATERIAL>
      <BOX>
        <TOTAL>3</TOTAL>
        <SERIES>
          <ITEM>0000000003</ITEM>
        </SERIES>
        <SERIES>
          <ITEM>0000000004</ITEM>
        </SERIES>
                <SERIES>
          <ITEM>0000000005</ITEM>
        </SERIES>
      </BOX>
    </MATERIAL>
  </PALLET>
</MESSAGE>
  • 1
    `//*[local-name()='ObjectEvent']` You should never have to use such hack. If the source element is in a namespace, use a prefix - see: https://stackoverflow.com/questions/34758492/xslt-transform-doesnt-work-until-i-remove-root-node/34762628#34762628 – michael.hor257k Aug 06 '19 at 05:16

1 Answers1

1

How about:

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:template match="/*">
    <MESSAGE>
        <PALLET>
            <xsl:variable name="total" select="count(ObjectEvent/epcList/epc)" />
            <xsl:for-each select="ObjectEvent">
                <MATERIAL>
                    <BOX>
                        <TOTAL>
                            <xsl:value-of select="$total"/>
                        </TOTAL>
                        <xsl:for-each select="epcList/epc">
                            <SERIES>
                                <ITEM>
                                    <xsl:value-of select="substring-after(substring-after(., '.'), '.')"/>
                                </ITEM>
                            </SERIES>
                        </xsl:for-each> 
                    </BOX>
                </MATERIAL>
            </xsl:for-each> 
        </PALLET>
    </MESSAGE>
</xsl:template>

</xsl:stylesheet>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51