This is a follow up to Martin Honnen's answer on here.
Here was my attempt at his suggestion: XSLT Fiddle link
In spreadsheet form, the data looks like this:
In XML this is the data input:
<VendorFile xmlns="http://etc/VendorFile">
<Row xmlns="">
<Meter>123</Meter>
<State>TX</State>
<StartDate/>
<Volume/>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/1/2024</StartDate>
<Volume>100</Volume>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/2/2024</StartDate>
<Volume>110</Volume>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/3/2024</StartDate>
<Volume>107</Volume>
</Row>
<Row xmlns="">
<Meter>456</Meter>
<State>OK</State>
<StartDate/>
<Volume/>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/1/2024</StartDate>
<Volume>200</Volume>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/2/2024</StartDate>
<Volume>205</Volume>
</Row>
<Row xmlns="">
<Meter></Meter>
<State></State>
<StartDate>1/3/2024</StartDate>
<Volume>210</Volume>
</Row>
</VendorFile>
My attempted XSLT is this (I have included the group tags to help understand):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:template match="/">
<output>
<xsl:for-each-group select="//Row" group-starting-with="Row[normalize-space(Meter) and normalize-space(State)]">
<group>
<xsl:for-each select="current-group()">
<!-- tail = Returns all but the first item in a sequence. -->
<xsl:apply-templates select="tail(current-group())"/>
</xsl:for-each>
</group>
</xsl:for-each-group>
<output>
</xsl:template>
<xsl:template match="Row">
<Row>
<!--<xsl:apply-templates select="current-group()[1]!(Meter, State), *"/>-->
<Meter><xsl:value-of select="current-group()[1]!(Meter)"/></Meter>
<State><xsl:value-of select="current-group()[1]!(State)"/></State>
<StartDate><xsl:value-of select="StartDate"/></StartDate>
<Volume><xsl:value-of select="Volume"/></Volume>
</Row>
</xsl:template>
<!--
<xsl:template match="Row">
<xsl:copy>
<xsl:apply-templates select="current-group()[1]!(Meter, State), *"/>
</xsl:copy>
</xsl:template>
-->
</xsl:stylesheet>
My current output is not what I want, but it's rather close. It seems that the startdate and volumes are occurring 3 times for each group.
<output>
<group>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/1/2024</StartDate>
<Volume>100</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/2/2024</StartDate>
<Volume>110</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/3/2024</StartDate>
<Volume>107</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/1/2024</StartDate>
<Volume>100</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/2/2024</StartDate>
<Volume>110</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/3/2024</StartDate>
<Volume>107</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/1/2024</StartDate>
<Volume>100</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/2/2024</StartDate>
<Volume>110</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/3/2024</StartDate>
<Volume>107</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/1/2024</StartDate>
<Volume>100</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/2/2024</StartDate>
<Volume>110</Volume>
</Row>
<Row><Meter>123</Meter><State>TX</State>
<StartDate>1/3/2024</StartDate>
<Volume>107</Volume>
</Row>
</group>
<group>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/1/2024</StartDate>
<Volume>200</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/2/2024</StartDate>
<Volume>205</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/3/2024</StartDate>
<Volume>210</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/1/2024</StartDate>
<Volume>200</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/2/2024</StartDate>
<Volume>205</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/3/2024</StartDate>
<Volume>210</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/1/2024</StartDate>
<Volume>200</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/2/2024</StartDate>
<Volume>205</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/3/2024</StartDate>
<Volume>210</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/1/2024</StartDate>
<Volume>200</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/2/2024</StartDate>
<Volume>205</Volume>
</Row>
<Row><Meter>456</Meter><State>OK</State>
<StartDate>1/3/2024</StartDate>
<Volume>210</Volume>
</Row>
</group>
</output>
Your main error is changing
<xsl:for-each-group select="//Row" group-starting-with="Row[normalize-space(Meter) and normalize-space(State)]">
<xsl:apply-templates select="tail(current-group())"/>
</xsl:for-each-group>
to
<xsl:for-each-group select="//Row" group-starting-with="Row[normalize-space(Meter) and normalize-space(State)]">
<group>
<xsl:for-each select="current-group()">
<!-- tail = Returns all but the first item in a sequence. -->
<xsl:apply-templates select="tail(current-group())"/>
</xsl:for-each>
</group>
</xsl:for-each-group>
that way you have inserted a for-each
which was not suggested but which for each item in the current group processes the tail of the current group.
Note also that I have reviewed the original answer and have improved the templates for Row
s to
<xsl:template match="Row">
<xsl:copy>
<xsl:apply-templates select="current-group()[1]!(Meter, State), * except (Meter, State)"/>
</xsl:copy>
</xsl:template>
I would then suggest to add <xsl:mode on-no-match="shallow-copy"/>
.