这是 Martin Honnen 在 here 上的回答的后续。
这是我对他的建议的尝试: XSLT 小提琴链接
以电子表格形式,数据如下所示:
在 XML 中,这是数据输入:
<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>
我尝试的 XSLT 是这样的(我已经包含了组标签以帮助理解):
<?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>
我当前的输出不是我想要的,但已经相当接近了。似乎每组的开始日期和数量都出现了 3 次。
<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>
你的主要错误正在改变
<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>
到
<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>
这样你就插入了一个
for-each
,这不是建议的,但对于当前组中的每个项目都会处理当前组的尾部。
另请注意,我已经审阅了原始答案,并将
Row
的模板改进为
<xsl:template match="Row">
<xsl:copy>
<xsl:apply-templates select="current-group()[1]!(Meter, State), * except (Meter, State)"/>
</xsl:copy>
</xsl:template>
然后我建议添加
<xsl:mode on-no-match="shallow-copy"/>
。