How to resolve Group and Sort withing XSLT - xslt

I have the following input message where the data needs to be grouped based on 'EmpNo' and 'Date' first. But the result should be taken from the latest date time from field 'lastDateTime'
Input XML:
<Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>3</Hours>
<EmpNo>825</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>4</Hours>
<EmpNo>826</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>5</Hours>
<EmpNo>827</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>3</Hours>
<EmpNo>825</EmpNo>
<lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>4</Hours>
<EmpNo>826</EmpNo>
<lastDateTime>2019-04-10T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>5</Hours>
<EmpNo>827</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>3</Hours>
<EmpNo>825</EmpNo>
<lastDateTime>2019-04-10T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>4</Hours>
<EmpNo>826</EmpNo>
<lastDateTime>2019-04-11T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>5</Hours>
<EmpNo>827</EmpNo>
<lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
</Record>
There could be many EmpNo with different Dates as well in the Input XML file. This needs to be grouped but it requires to extract only that particular node where lastDateTime is the latest.
Expected Result:
<Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>6</Hours>
<EmpNo>825</EmpNo>
<lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
<Rate>1142</Rate>
<Code>13</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>4</Hours>
<EmpNo>826</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1140</Rate>
<Code>11</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>11</Hours>
<EmpNo>827</EmpNo>
<lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
<Rate>1147</Rate>
<Code>18</Code>
</Record>
</Record>
I tried to write the following code but no luck.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf" exclude-result-prefixes="#all" version="2.0">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="Record">
<xsl:copy>
<xsl:for-each-group select="Record" group-by="EmpNo">
<xsl:for-each-group select="current-group()" group-by="Date">
<xsl:copy>
<EmpNo>
<xsl:value-of select="EmpNo"/>
</EmpNo>
<Date>
<xsl:value-of select="Date"/>
</Date>
<lastDateTime>
<xsl:value-of select="max(current-group()/lastDateTime/xs:dateTime(.))"/>
</lastDateTime>
<Hours>
<xsl:value-of select="Hours[Date=max(current-group()/lastDateTime/xs:dateTime(.))]"/>
</Hours>
</xsl:copy>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>

Based on your description I think you want
<xsl:template match="Record">
<xsl:copy>
<xsl:for-each-group select="Record" group-by="EmpNo">
<xsl:for-each-group select="current-group()" group-by="Date">
<xsl:for-each select="current-group()">
<xsl:sort select="xs:dateTime(lastDateTime)"/>
<xsl:if test="position() = last()">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
However, result at https://xsltfiddle.liberty-development.net/ncdD7mB is
<Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>3</Hours>
<EmpNo>825</EmpNo>
<lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>4</Hours>
<EmpNo>826</EmpNo>
<lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
<Record>
<Date>2019-04-01T00:00:00.000</Date>
<Hours>5</Hours>
<EmpNo>827</EmpNo>
<lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
<Rate>1139</Rate>
<Code>102486</Code>
</Record>
</Record>
I am not sure from which item in a group you want to take the not grouped child elements.

Related

XSLT logic to add a sequence for the combination of elements with same dates and ID field

I am struggling to create logic for transformation.
Logic: "Seq" A sequential number used to make a unique key when the ID and Date fields are equal.
<root>
<Record>
<ID>11</ID>
<date>2020-03-11-07:00</date>
<quantity>10</quantity>
</Record>
<Record>
<ID>13</ID>
<date>2020-03-12-07:00</date>
<quantity>20</quantity>
</Record>
<Record>
<ID>15</ID>
<date>2020-03-13-07:00</date>
<quantity>40</quantity>
</Record>
<Record>
<ID>11</ID>
<date>2020-03-11-07:00</date>
<quantity>5</quantity>
</Record>
<Record>
<ID>13</ID>
<date>2020-03-17-07:00</date>
<quantity>100</quantity>
</Record>
</root>
to, Output
ID,seq,Date,quantity
11,1,2020-03-11-07:00,10
11,2,2020-03-11-07:00,5
13,1,2020-03-12-07:00,20
15,1,2020-03-13-07:00,40
13,1,2020-03-17-07:00,100
In XSLT 3 it is a simple grouping problem with a composite key:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text" />
<xsl:template match="root">
<xsl:text>ID,seq,Date,quantity
</xsl:text>
<xsl:for-each-group select="Record" composite="yes" group-by="ID, date">
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="Record">
<xsl:value-of select="ID, position(), date, quantity" separator=","/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/93dFepy
XSLT 3 can be used with Saxon 9.8 and later or AltovaXML 2017 R3 or later.

Flatten XML after copy

I have a requirement to create a copy of the xml record based on a repeating field which I am able to do so, however I need the result to be flattened
I have tried to use variables and copying them to the output
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Hire>
<xsl:for-each select="Hire/Record">
<xsl:variable name="var_record" select="./*
[not(name()='Sweldo')]" />
<xsl:for-each select="Sweldo">
<xsl:variable name="var_SWELDO" select=".">
</xsl:variable>
<Record>
<xsl:copy-of select="$var_record" />
<xsl:copy-of select="$var_SWELDO" />
</Record>
</xsl:for-each>
</xsl:for-each>
</Hire>
</xsl:template>
</xsl:stylesheet>
The input is
<?xml version="1.0" encoding="UTF-8"?>
<Hire>
<Record>
<XRefCode>XX</XRefCode>
<EmployeeNumber>161</EmployeeNumber>
<BirthDate>1985-04-09</BirthDate>
<SocialSecurityNumber>XXXXXXX</SocialSecurityNumber>
<FirstName>XX</FirstName>
<LastName>XX</LastName>
<MiddleName>D</MiddleName>
<Sweldo>
<sahod>ONE MILLION</sahod>
</Sweldo>
<Sweldo>
<sahod>1 BILLION</sahod>
</Sweldo>
</Record>
</Hire>
The output I am getting is
<?xml version="1.0"?>
<Hire>
<Record>
<XRefCode>161</XRefCode>
<EmployeeNumber>161</EmployeeNumber>
<BirthDate>1985-04-09</BirthDate>
<SocialSecurityNumber>999-81-9462</SocialSecurityNumber>
<FirstName>XXX</FirstName>
<LastName>XXXXX</LastName>
<MiddleName>D</MiddleName>
<Sweldo>
<sahod>ONE MILLION</sahod>
</Sweldo>
</Record>
<Record>
<XRefCode>161</XRefCode>
<EmployeeNumber>161</EmployeeNumber>
<BirthDate>1985-04-09</BirthDate>
<SocialSecurityNumber>999-81-9462</SocialSecurityNumber>
<FirstName>XXX</FirstName>
<LastName>XXXX</LastName>
<MiddleName>D</MiddleName>
<Sweldo>
<sahod>1 BILLION</sahod>
</Sweldo>
</Record>
</Hire>
However I need the following format
<?xml version="1.0"?>
<Hire>
<Record>
<XRefCode>161</XRefCode>
<EmployeeNumber>161</EmployeeNumber>
<BirthDate>1985-04-09</BirthDate>
<SocialSecurityNumber>999-81-9462</SocialSecurityNumber>
<FirstName>XXXX</FirstName>
<LastName>XXXXXX</LastName>
<MiddleName>D</MiddleName>
<sahod>ONE MILLION</sahod>
</Record>
<Record>
<XRefCode>161</XRefCode>
<EmployeeNumber>161</EmployeeNumber>
<BirthDate>1985-04-09</BirthDate>
<SocialSecurityNumber>999-81-9462</SocialSecurityNumber>
<FirstName>XXXX</FirstName>
<LastName>XXXX</LastName>
<MiddleName>D</MiddleName>
<sahod>1 BILLION</sahod>
</Record>
</Hire>
Is there a way to completely remove the element?
Please check and update following code:-
<xsl:for-each select="Sweldo">
**change to**
<xsl:for-each select="Sweldo/sahod">

XSLT To filter out records with letters

We have a requirement to filter records with characters in numeric fields and report them separately. I did come across the following question which has been answered -
XPATH To filter out records with letters
However is there a way to mark these records with a flag or collect them in a variable as we need to report these records as invalid records. If we delete them completely the problem is that we do not have a clue on which of them were invalid.
Please suggest.
Thank You!
Input:
<?xml version="1.0" encoding="UTF-8"?>
<payload>
<records>
<record>
<number>123</number>
</record>
<record>
<number>456</number>
</record>
<record>
<number>78A</number>
</record>
</records>
</payload>
Output:
<?xml version="1.0" encoding="UTF-8"?>
<payload>
<records>
<record>
<number>123</number>
</record>
<record>
<number>456</number>
</record>
</records>
</payload>
XSLT solution from the link above:
<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:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record[translate(number, '0123456789', '')]"/>
</xsl:stylesheet>
After the match, output the original element with whatever "flag" you want (attribute, comment, processing instruction, etc.).
Example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record[string(number(number))='NaN']">
<record invalid="true">
<xsl:apply-templates select="#*|node()"/>
</record>
</xsl:template>
</xsl:stylesheet>
Output
<payload>
<records>
<record>
<number>123</number>
</record>
<record>
<number>456</number>
</record>
<record invalid="true">
<number>78A</number>
</record>
</records>
</payload>
You can still use your original match if you'd like.
Edit to handle multiple number (fields) and identify the specific fields (columns) at the record level.
Modified XML input example:
<payload>
<records>
<record>
<number>123</number>
</record>
<record>
<number>456</number>
</record>
<record>
<number>321</number>
<number>78A</number>
<number>654</number>
<number>abc</number>
</record>
</records>
</payload>
Updated XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="record">
<xsl:variable name="invalidCols">
<xsl:apply-templates select="*" mode="invalid"/>
</xsl:variable>
<record>
<xsl:if test="string($invalidCols)">
<xsl:attribute name="invalidCols">
<xsl:value-of select="normalize-space($invalidCols)"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="#*|node()"/>
</record>
</xsl:template>
<xsl:template match="number[string(number(.))='NaN']" mode="invalid">
<xsl:number/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="*" mode="invalid"/>
</xsl:stylesheet>
Output
<payload>
<records>
<record>
<number>123</number>
</record>
<record>
<number>456</number>
</record>
<record invalidCols="2 4">
<number>321</number>
<number>78A</number>
<number>654</number>
<number>abc</number>
<number>123456</number>
</record>
</records>
</payload>

Need some help converting an XML with XSLT 1.0

Need some help regarding the XSLT transformation of a flat file schema. Is it possible to combine the direct children of the Record node into one containing Record node? Child 512 is required and has min and max occurrence of 1 and marks the beginning of a new Record node.
Input:
<ns0:Root xmlns="">
<Header>
<node01>AA</node01>
<node02>123</node02>
</Header>
<Record>
<512>
<node01>BB</node01>
<node02>123</node02>
</512>
</Record>
<Record>
<513>
<node01>CC</node01>
<node02>123</node02>
</513>
</Record>
<Record>
<512>
<node01>DD</node01>
<node02>123</node02>
</512>
</Record>
<Record>
<515>
<node01>JJ</node01>
<node02>123</node02>
</515>
</Record>
<Record>
<512>
<node01>EE</node01>
<node02>123</node02>
</512>
</Record>
<Record>
<513>
<node01>FF</node01>
<node02>123</node02>
</513>
</Record>
<Record>
<514>
<node01>GG</node01>
<node02>123</node02>
</514>
<514>
<node01>HH</node01>
<node02>123</node02>
</514>
</Record>
<Footer>
<node01>II</node01>
<node02>123</node02>
</Footer>
</ns0:Root>
Desired Output:
<ns0:Root xmlns="">
<Header>
<item01>AA</item01>
<item02>123</item02>
</Header>
<Record>
<512>
<item01>BB</item01>
<item02>123</item02>
</512>
<513>
<item01>CC</item01>
<item02>123</item02>
</513>
</Record>
<Record>
<512>
<item01>DD</item01>
<item02>123</item02>
</512>
<515>
<item01>JJ</item01>
<item02>123</item02>
</515>
</Record>
<Record>
<512>
<item01>EE</item01>
<item02>123</item02>
</512>
<513>
<item01>FF</item01>
<item02>123</item02>
</513>
<514>
<item01>GG</item01>
<item02>123</item02>
</514>
<514>
<item01>HH</item01>
<item02>123</item02>
</514>
</Record>
<Footer>
<item01>II</item01>
<item02>123</item02>
</Footer>
</ns0:Root>
Thank you and kind regards
Philipp
P.S.: XSLT 2.0 is not available.
That's not legal XML (element names can't start with numbers), but supposing you renamed all the invalid elements to start with "r", you can do the following:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Record[r512]">
<xsl:copy>
<xsl:apply-templates select="." mode="iterate" />
</xsl:copy>
</xsl:template>
<xsl:template match="Record" />
<xsl:template match="Record" mode="iterate">
<xsl:apply-templates />
<xsl:apply-templates select="following-sibling::Record[1][not(r512)]"
mode="iterate"/>
</xsl:template>
</xsl:stylesheet>
When run on this input:
<ns0:Root xmlns="" xmlns:ns0="nsss">
<Header>
<node01>AA</node01>
<node02>123</node02>
</Header>
<Record>
<r512>
<node01>BB</node01>
<node02>123</node02>
</r512>
</Record>
<Record>
<r513>
<node01>CC</node01>
<node02>123</node02>
</r513>
</Record>
<Record>
<r512>
<node01>DD</node01>
<node02>123</node02>
</r512>
</Record>
<Record>
<r515>
<node01>JJ</node01>
<node02>123</node02>
</r515>
</Record>
<Record>
<r512>
<node01>EE</node01>
<node02>123</node02>
</r512>
</Record>
<Record>
<r513>
<node01>FF</node01>
<node02>123</node02>
</r513>
</Record>
<Record>
<r514>
<node01>GG</node01>
<node02>123</node02>
</r514>
<r514>
<node01>HH</node01>
<node02>123</node02>
</r514>
</Record>
<Footer>
<node01>II</node01>
<node02>123</node02>
</Footer>
</ns0:Root>
Produces:
<ns0:Root xmlns:ns0="nsss">
<Header>
<node01>AA</node01>
<node02>123</node02>
</Header>
<Record>
<r512>
<node01>BB</node01>
<node02>123</node02>
</r512>
<r513>
<node01>CC</node01>
<node02>123</node02>
</r513>
</Record>
<Record>
<r512>
<node01>DD</node01>
<node02>123</node02>
</r512>
<r515>
<node01>JJ</node01>
<node02>123</node02>
</r515>
</Record>
<Record>
<r512>
<node01>EE</node01>
<node02>123</node02>
</r512>
<r513>
<node01>FF</node01>
<node02>123</node02>
</r513>
<r514>
<node01>GG</node01>
<node02>123</node02>
</r514>
<r514>
<node01>HH</node01>
<node02>123</node02>
</r514>
</Record>
<Footer>
<node01>II</node01>
<node02>123</node02>
</Footer>
</ns0:Root>

Implementing bit tricky logic in xslt 1.0 transformation

I am finding bit difficulty to implement following logic while doing transformation using xslt 1.0.
Here is my requirement:
I need to define following logic on hours worked by an employee.
1. anything over 8 will be OT else Regular in a day.
2. if worked continuously for 3 days then 3rd day hours would be double time.
Here is an example:
Input:
<Input>
<Record>
<EmpId>1</EmpId>
<Date></Date>
<Hours></Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/1/2012</Date>
<Hours>6</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/1/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/2/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/2/2012</Date>
<Hours></Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/3/2012</Date>
<Hours>3</Hours>
</Record>
<Record>
<EmpId>2</EmpId>
<Date>12/1/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>2</EmpId>
<Date>12/1/2012</Date>
<Hours></Hours>
</Record>
</Input>
Output:
<Output>
<Record>
<EmployeeId>1</EmployeeId>
<Detail>
<Date>12/1/2012</Date>
<RegHours>8</Reghours>
<OTHours>2</OTHours>
</Detail>
<Detail>
<Date>12/2/2012</Date>
<RegHours>4</Reghours>
</Detail>
<Detail>
<Date>12/3/2012</Date>
<DTHours>3</DThours>
</Detail>
</Record>
<Record>
<EmployeeId>2</EmployeeId>
<Detail>
<Date>12/1/2012</Date>
<RegHours>4</Reghours>
</Detail>
<Detail>
</Record>
</Output>
Would appreciate for any help.
Thanks..
Abhi
This transformation:
<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="kRecByEmpId" match="Record[Date/node() and Hours/node()]"
use="EmpId"/>
<xsl:key name="kRecByEmpIdDate" match="Record[Date/node() and Hours/node()]"
use="concat(EmpId,'+',Date)"/>
<xsl:template match=
"Record[generate-id()=generate-id(key('kRecByEmpId',EmpId)[1])]">
<Record>
<EmployeeId>
<xsl:value-of select="EmpId"/>
</EmployeeId>
<xsl:apply-templates mode="datetime" select=
"key('kRecByEmpId', EmpId)
[generate-id()
=
generate-id(key('kRecByEmpIdDate',
concat(EmpId,'+',Date)
)[1]
)
]
"/>
</Record>
</xsl:template>
<xsl:template match="Record" mode="datetime">
<Detail>
<xsl:copy-of select="Date"/>
<xsl:variable name="vTotal" select=
"sum(key('kRecByEmpIdDate', concat(EmpId,'+',Date))/Hours)"/>
<RegHours>
<xsl:value-of select="8*($vTotal >= 8) + $vTotal*(not($vTotal >= 8))"/>
</RegHours>
<xsl:if test="$vTotal > 8">
<OTHours>
<xsl:value-of select="$vTotal -8"/>
</OTHours>
</xsl:if>
</Detail>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when applied on the provided XML document:
<Input>
<Record>
<EmpId>1</EmpId>
<Date></Date>
<Hours></Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/1/2012</Date>
<Hours>6</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/1/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/2/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/2/2012</Date>
<Hours></Hours>
</Record>
<Record>
<EmpId>1</EmpId>
<Date>12/3/2012</Date>
<Hours>3</Hours>
</Record>
<Record>
<EmpId>2</EmpId>
<Date>12/1/2012</Date>
<Hours>4</Hours>
</Record>
<Record>
<EmpId>2</EmpId>
<Date>12/1/2012</Date>
<Hours></Hours>
</Record>
</Input>
produces the wanted, correct result:
<Record>
<EmployeeId>1</EmployeeId>
<Detail>
<Date>12/1/2012</Date>
<RegHours>8</RegHours>
<OTHours>2</OTHours>
</Detail>
<Detail>
<Date>12/2/2012</Date>
<RegHours>4</RegHours>
</Detail>
<Detail>
<Date>12/3/2012</Date>
<RegHours>3</RegHours>
</Detail>
</Record>
<Record>
<EmployeeId>2</EmployeeId>
<Detail>
<Date>12/1/2012</Date>
<RegHours>4</RegHours>
</Detail>
</Record>