Xml xsl group by随时间从日期到等于日期从
我正在使用XSLT2.0转换为新的XML 这是我的xml结构:Xml xsl group by随时间从日期到等于日期从,xml,xslt,group-by,Xml,Xslt,Group By,我正在使用XSLT2.0转换为新的XML 这是我的xml结构: <?xml version="1.0" encoding="UTF-8"?> <bills> <bill id="1"> <rz_from>05.11.2011</rz_from> <rz_to>31.12.2011</rz_to> <rz_price_pro_unit>4</
<?xml version="1.0" encoding="UTF-8"?>
<bills>
<bill id="1">
<rz_from>05.11.2011</rz_from>
<rz_to>31.12.2011</rz_to>
<rz_price_pro_unit>4</rz_price_pro_unit>
<rz_units>7</rz_units>
</bill>
<bill id="2">
<rz_from>1.1.2012</rz_from>
<rz_to>31.3.2012</rz_to>
<rz_price_pro_unit>4</rz_price_pro_unit>
<rz_units>9</rz_units>
</bill>
<bill id="3">
<rz_from>1.5.2012</rz_from>
<rz_to>31.12.2012</rz_to>
<rz_price_pro_unit>4</rz_price_pro_unit>
<rz_units>21</rz_units>
</bill>
<bill id="4">
<rz_from>1.1.2013</rz_from>
<rz_to>31.12.2013</rz_to>
<rz_price_pro_unit>5</rz_price_pro_unit>
<rz_units>45</rz_units>
</bill>
<bill id="5">
<rz_from>1.1.2014</rz_from>
<rz_to>31.12.2014</rz_to>
<rz_price_pro_unit>5</rz_price_pro_unit>
<rz_units>51</rz_units>
</bill>
</bills>
05.11.2011
31.12.2011
4.
7.
1.1.2012
31.3.2012
4.
9
1.5.2012
31.12.2012
4.
21
1.1.2013
31.12.2013
5.
45
1.1.2014
31.12.2014
5.
51
我需要按照以下规则对账单节点进行分组:
- 每件的价格是一样的
- 日期(rz_from-1天)等于上一个节点的日期(rz_to)
- 单位计数应为分组值之和
- 工程量清单:16个单位-价格4(工程量清单1+2)
- 工程量清单:21件-价格4(工程量清单3)
- 工程量清单:96个单位-价格5(工程量清单4+5)
我想你有足够的时间回答两三个问题 首先,这里没有这样的分组,因为没有可以分组的公共值。我认为您需要选择每个组中的第一个账单(即不延续“链”的账单),然后对组中的成员应用“兄弟递归” 更复杂的是,您的日期不是ISO-8601日期(YYYY-MM-DD),因此在转换日期之前,无法对其执行任何计算。我将为此使用自定义函数 下面的样式表假设账单是按时间顺序排序的(尽管这个假设对于解决问题不是必需的): XSLT2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="xs my">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:function name="my:get-as-date" as="xs:date">
<xsl:param name="dmy"/>
<xsl:variable name="d" select="substring-before($dmy, '.')"/>
<xsl:variable name="m" select="substring-before(substring-after($dmy, '.'), '.')"/>
<xsl:variable name="y" select="substring-after(substring-after($dmy, '.'), '.')"/>
<xsl:value-of select="concat(format-number(xs:integer($y), '0000'), '-', format-number(xs:integer($m), '00'), '-', format-number(xs:integer($d), '00'))"/>
</xsl:function>
<xsl:template match="/bills">
<xsl:copy>
<xsl:apply-templates select="bill[not(preceding-sibling::bill[1]/my:get-as-date(rz_to) + xs:dayTimeDuration('P1D') = my:get-as-date(rz_from) and preceding-sibling::bill[1]/rz_price_pro_unit = rz_price_pro_unit)]" mode="init"/>
</xsl:copy>
</xsl:template>
<xsl:template match="bill" mode="init">
<group>
<xsl:copy-of select="rz_from"/>
<xsl:apply-templates select="." mode="collect"/>
</group>
</xsl:template>
<xsl:template match="bill" mode="collect">
<xsl:param name="units" select="0"/>
<xsl:choose>
<xsl:when test="following-sibling::bill[1]/my:get-as-date(rz_from) = my:get-as-date(rz_to) + xs:dayTimeDuration('P1D') and following-sibling::bill[1]/rz_price_pro_unit = rz_price_pro_unit">
<xsl:apply-templates select="following-sibling::bill[1]" mode="collect">
<xsl:with-param name="units" select="$units + rz_units"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="rz_to"/>
<xsl:copy-of select="rz_price_pro_unit"/>
<rz_units>
<xsl:value-of select="$units + rz_units"/>
</rz_units>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="utf-8"?>
<bills>
<group>
<rz_from>05.11.2011</rz_from>
<rz_to>31.3.2012</rz_to>
<rz_price_pro_unit>4</rz_price_pro_unit>
<rz_units>16</rz_units>
</group>
<group>
<rz_from>1.5.2012</rz_from>
<rz_to>31.12.2012</rz_to>
<rz_price_pro_unit>4</rz_price_pro_unit>
<rz_units>21</rz_units>
</group>
<group>
<rz_from>1.1.2013</rz_from>
<rz_to>31.12.2014</rz_to>
<rz_price_pro_unit>5</rz_price_pro_unit>
<rz_units>96</rz_units>
</group>
</bills>
05.11.2011
31.3.2012
4.
16
1.5.2012
31.12.2012
4.
21
1.1.2013
31.12.2014
5.
96
到目前为止,您尝试了什么?你能发布你的XSLT吗。。