1

I have following requirement where I need your help to transform the XML using XSLT 2.0.

  1. <Workers> node for a single worker need to be inserted as many time as total number of <Days> for a worker e.g. if total number of days for a worker is 5, <Workers><Worker> need to be present 5 times holding the data for that worker.
  2. Each time new nodes are inserted for a worker, <StartDate> need to be incremented by a day and map it's value to new element WorkerStartDate

  3. Each time new nodes are created, a new element <RecordNumber> needs to be inserted holding the value of that loop.

Input XML

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <id>1234</id>
        <loc>New York</loc>
        <Days>5</Days>
        <StartDate>2019-02-01</StartDate>
    </Worker>
</Workers>

Expected Output XML after XSLT transformation

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>2</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-03</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>3</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-04</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>4</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-05</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>5</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-06</WorkerStartDate>
    </Worker>
</Workers>

I’m able to get following output <RecordNumber> and <WorkerStartDate> are returning wrong data

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>
<Workers>
    <Worker>
        <WorkerId>1234</WorkerId>
        <WorkerLoc>New York</WorkerLoc>
        <RecordNumber>1</RecordNumber>
        <WorkerDays>1</WorkerDays>
        <WorkerStartDate>2019-02-02</WorkerStartDate>
    </Worker>
</Workers>

My XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>

    <xsl:template match="/">
        <xsl:variable name="start" select="1"/>
        <xsl:variable name="counter" select="Workers/Worker/Days"/>
        <xsl:variable name="Records" select="Workers/Worker"/>
        <xsl:for-each select="$start to $counter">
            <xsl:apply-templates select="$Records" mode="replicate">
                <xsl:with-param name="data" select="."/>
            </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="Worker" mode="replicate">
        <xsl:param name="data"/>
        <Workers>
            <Worker>
                <WorkerId><xsl:value-of select="id"/></WorkerId>
                <WorkerLoc><xsl:value-of select="loc"/></WorkerLoc>
                <RecordNumber><xsl:value-of select="position()"/></RecordNumber>
                <WorkerDays>1</WorkerDays>
                <WorkerStartDate><xsl:value-of select="xs:date(StartDate) + xs:dayTimeDuration('P1D')"/>
                </WorkerStartDate>
            </Worker>
        </Workers>
    </xsl:template>

</xsl:stylesheet>

Current output XML has following issues:

  1. <WorkerStartDate> always returned as 1 where as WorkerStartDate is expected to increment by a day based on the XML element
  2. <RecordNumber> always returned as 1 where as RecordNumber is expected to increment by one such as 1,2,3..
  3. Not a big issue - <WorkerDays> needs to always return 1. Now that I hard coded this value. Not sure if there is an efficient way to print 1 as value until the loop ends.

Can someone help me fix the issues that I have please?

1 Answer 1

1

You have defined that parameter named data that is bound to the integer value you process in the for-each with the to expression so you can simply use that parameter with

<RecordNumber><xsl:value-of select="$data"/></RecordNumber>

and

<WorkerStartDate>
  <xsl:value-of select="xs:date(StartDate) + xs:dayTimeDuration('P1D') * $data"/>
</WorkerStartDate>

https://xsltfiddle.liberty-development.net/gWvjQeT

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.