我想在xslt上寻求您的专业知识。 我有XML的日期范围,例如
=
现在我需要每个日期发送1行,例如对于ABC1 id,我需要以startdate enddate作为增量发送10条记录。
转换后,数据应如下所示
<data>
<ID>ABC1</ID>
<Start_Date>2018-05-01</Start_Date>
<End_Date>2018-05-10</End_Date>
<data>
<ID>ABC2</ID>
<Start_Date>2018-05-10</Start_Date>
<End_Date>2018-05-12</End_Date>
<data>
<root>
直到ABC1这样的总数我们需要有10个数据部分和ABC2 2数据部分。
请指导我如何在XSLT中实现逻辑。
答案 0 :(得分:1)
正如您所说,您至少可以使用XSLT 2,您可以利用xs:date
数据类型和算法操作(如减法XSLT / XPath 2及更高版本)支持计算天数差异,然后处理每个项目正确日期的时间:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="increment" on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="data">
<xsl:variable name="data" select="."/>
<xsl:for-each select="0 to days-from-duration(xs:date(End_Date) - xs:date(Start_Date))">
<xsl:apply-templates select="$data" mode="increment">
<xsl:with-param name="date" tunnel="yes" select="xs:date($data/Start_Date) + xs:dayTimeDuration('P1D') * ."/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="data/Start_Date | data/End_Date" mode="increment">
<xsl:param name="date" tunnel="yes"/>
<xsl:copy>
<xsl:value-of select="$date"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是XSLT 3,但仅适用于您可以用
替换XSLT 2的xsl:mode
内容
<xsl:template match="@* | node()" mode="#default increment">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/gWmuiJ6的XSLT 3在线示例。