This is the input XML:
<Move-Afile>
<Afile>
<Item>
<PackNumber>1234</PackNumber>
</Item>
<Item>
<PackNumber>567</PackNumber>
</Item>
<Item>
<PackNumber>567</PackNumber>
</Item>
<Item>
<PackNumber>126</PackNumber>
</Item>
<Item>
<PackNumber>876</PackNumber>
</Item>
</Afile>
</Move-Afile>
<Item>
is an unbounded element which contains <PackNumber>
as a child element. For each pack number we need to increment the counter variable, but here one condition is present like if previous <PackNumber>
is equal to current <PackNumber>
we have to ignore the counter (there is no need to increment) like below output.
Inside the for-each
, can we get the counter like below XSLT sample?
This is my XSLT template
<xsl:template match="/">
<A>
<target>
<xsl:for-each select="/inp1:Move-Afile/inp1:Afile/inp1:Item/inp1:PalletNumber">
<xsl:variable name="count">
<!-- get the count here-->
</xsl:variable>
<counter>$count</counter>
<PNumber><xsl:value-of select="."/></PNumber>
</xsl:for-each>
</target>
</A>
</xsl:template>
This is the XML output:
<A>
<target>
<Item>
<counter>1</counter><!-- if previous <PackNumber> is not equal to current <PackNumber> increment the count-->
<PNumber>1234</PNumber>
</Item>
<Item>
<counter>2</counter><!-- if previous <PackNumber> is not equal to current <PackNumber> increment the count-->
<PNumber>567</PNumber>
</Item>
<Item><!-- if previous <PackNumber> is equal to current <PackNumber> ignore the count-->no need to increment
<PNumber>567</PNumber>
</Item>
<Item>
<counter>3</counter><!-- if previous <PackNumber> is not equal to current <PackNumber> increment the count-->
<PNumber>126</PNumber>
</Item>
<Item><!-- if previous <PackNumber> is equal to current <PackNumber> ignore the count-->no need to increment
<PNumber>126</PNumber>
</Item>
</target>
</A>
XML output 2:
<?xml version="1.0"?>
<A>
<target>
<counter>1</counter>
<PNumber>1234</PNumber>
<counter>2</counter>
<PNumber>567</PNumber>
<!-- IF PNumber is equal we have to ignore the Total loop -->
<counter>3</counter>
<PNumber>126</PNumber>
<counter>4</counter>
<PNumber>876</PNumber>
</target>
</A>
Try this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" />
<xsl:template match="PackNumber">
<xsl:if test="not(preceding::PackNumber =.)" >
<!-- if previous <PackNumber> is not equal to current <PackNumber> t-->
<counter>
<xsl:value-of select="count(preceding::PackNumber[not(preceding::PackNumber= .)])+1"/>
</counter>
</xsl:if>
<PNumber>
<xsl:value-of select="."/>
</PNumber>
</xsl:template>
<xsl:template match="/">
<A>
<target>
<xsl:apply-templates select="//Item"/>
</target>
</A>
</xsl:template>
</xsl:stylesheet>
Update according the changed question:
get the count here (inside a for each loop as variable)
Try this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()" />
<xsl:template match="PackNumber" mode="count">
<xsl:value-of select="count(preceding::PackNumber
[not(preceding::PackNumber= .)and not( . = current()/. ) ])+1"/>
</xsl:template>
<xsl:template match="/">
<A>
<target>
<xsl:for-each select="//Item/PackNumber">
<xsl:variable name="count">
<xsl:apply-templates select="." mode="count"/>
</xsl:variable>
<counter>
<xsl:value-of select="$count"/>
</counter>
<PNumber>
<xsl:value-of select="."/>
</PNumber>
</xsl:for-each>
</target>
</A>
</xsl:template>
</xsl:stylesheet>
Update Output:
<?xml version="1.0"?>
<A>
<target>
<counter>1</counter>
<PNumber>1234</PNumber>
<counter>2</counter>
<PNumber>567</PNumber>
<counter>2</counter>
<PNumber>567</PNumber>
<counter>3</counter>
<PNumber>126</PNumber>
<counter>4</counter>
<PNumber>876</PNumber>
</target>
</A>
Here is a short and very efficient solution, using Muenchian grouping:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kPackNByVal" match="PackNumber" use="."/>
<xsl:template match="Afile">
<A>
<target>
<xsl:apply-templates select=
"*/*[generate-id() = generate-id(key('kPackNByVal',.)[1])]"/>
</target>
</A>
</xsl:template>
<xsl:template match="PackNumber">
<counter><xsl:value-of select="position()"/></counter>
<PNumber><xsl:value-of select="."/></PNumber>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<Move-Afile>
<Afile>
<Item>
<PackNumber>1234</PackNumber>
</Item>
<Item>
<PackNumber>567</PackNumber>
</Item>
<Item>
<PackNumber>567</PackNumber>
</Item>
<Item>
<PackNumber>126</PackNumber>
</Item>
<Item>
<PackNumber>876</PackNumber>
</Item>
</Afile>
</Move-Afile>
the wanted, correct result is produced:
<A>
<target>
<counter>1</counter>
<PNumber>1234</PNumber>
<counter>2</counter>
<PNumber>567</PNumber>
<counter>3</counter>
<PNumber>126</PNumber>
<counter>4</counter>
<PNumber>876</PNumber>
</target>
</A>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With