sandeep np
sandeep np

Reputation: 1

Increment the repeated value in xslt inside for-each

Here I want to count/Increment the repeated emp_no using for each.

and I just want to concatenate emp_no with duplicate no count..

Here is my XSLT style sheet.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array" exclude-result-prefixes="#all"
    version="3.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:param name="input"/>

    <xsl:variable name="newline" select="'&#10;'"/>
    <xsl:template match="/" name="xsl:initial-template">
        <xsl:variable name="input-as-map" select="parse-json($input)" as="map(*)"/>
        <root>

            <file1>
                <xsl:for-each select="$input-as-map?file1?*">
                    <xsl:value-of select="$newline"/>
                    <xsl:value-of select="concat(?emp_no,',',count(?emp_no))"/>
                    <xsl:value-of select="$newline"/>
                </xsl:for-each>
            </file1>


        </root>
    </xsl:template>

</xsl:stylesheet>

input json:-

{
    "file1": [
        {
            "emp_no": "0002"
        },
        {
            "emp_no": "0009"
        },
        {
            "emp_no": "0002"
        },
        {
            "emp_no": "0009"
        },
         {
            "emp_no": "0009"
        }
    ]
}

Expected output:-

<root>
   <file1>
0002,1
0009,1
0002,2
0009,2
0009,3
</file1>
</root>

Any suggestions also would be helpful.

Upvotes: 0

Views: 215

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167506

Here is Mike's third suggestion spelled out:

  <file>
    <xsl:value-of 
      select="fold-left(
                parse-json($json)?file1?*, 
                map{}, 
                function($am, $m) { 
                  let $c := head($am)($m?emp_no),
                      $new-am := map:put(head($am), $m?emp_no, if (empty($c)) then 1 else $c + 1)
                  return ($new-am, tail($am), $m?emp_no || ',' || $new-am($m?emp_no))
                }
              ) => tail()"
      separator="&#10;"/>
  </file>

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163322

One solution would be to replace the xsl:for-each with xsl:iterate, maintaining a parameter value containing a map from emp_no to an integer counter.

Another would be to convert the array to XML and use xsl:number.

Or you could use fn:fold-left(), again maintaining a map from emp_no to an integer counter as you step through the array.

None of them particularly easy, I'm afraid: perhaps someone else has a better idea.

Upvotes: 1

Related Questions