SOA 转换中的 XSLT 映射以获取上个月的最大日期

Posted

技术标签:

【中文标题】SOA 转换中的 XSLT 映射以获取上个月的最大日期【英文标题】:XSLT mapping in SOA transformation to get max date from last month 【发布时间】:2020-02-26 08:11:07 【问题描述】:

我正在尝试创建一个 XSLT 映射以获取上个月的最后(最大)天。

例如-如果我将 2019-10-17 的值传递给映射,它应该返回 2019-09-30。我在这里使用的日期格式是 YYYY-MM-DD。

尝试从当前数据中获取月份并将其减去 1,以便返回上个月。但我无法获得上个月的最大日期。

xp20:month-from-dateTime (/ns0:ddSelecCorpoMasterOutputCollection/ns0:ddSelecCorpoMasterOutput/ns0:FROM_DATE_FILTER ) - 1

输入-系统日期 o/p- 上个月的最大日期 例如- i/p-2019-10-18 o/p- 2019-09-30

提前致谢。

【问题讨论】:

请指定 XSLT 版本。 XSLT 2.0 引入了一个广泛的日期/时间库,因此它产生了很大的不同。此外,如果您仍在使用旧的 XSLT 1.0,您可能可以访问 exslt:date 扩展函数库的实现。 【参考方案1】:

在纯 XSLT 1.0 中查找上个月的最后一天:

<xsl:template name="end-of-last-month">
    <xsl:param name="date"/>
    <!-- extract date components -->
    <xsl:variable name="year" select="substring($date, 1, 4)"/>
    <xsl:variable name="month" select="substring($date, 6, 2)"/>
    <!-- go one month back -->
    <xsl:variable name="y" select="$year - ($month = 1)"/>
    <xsl:variable name="m" select="($month + 10) mod 12 + 1"/>
    <!-- get month length -->
    <xsl:variable name="cal" select="'312831303130313130313031'"/>
    <xsl:variable name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
    <xsl:variable name="month-length" select="substring($cal, 2*($m - 1) + 1, 2) + ($m=2 and $leap)" />
    <!-- output -->
    <xsl:value-of select="$y" />
    <xsl:value-of select="format-number($m, '-00')" />
    <xsl:text>-</xsl:text>
    <xsl:value-of select="$month-length" />
</xsl:template>

例子:

XML

<input>
    <date>2019-01-15</date>
    <date>2019-02-15</date>
    <date>2019-03-15</date>
    <date>2019-04-15</date>
    <date>2019-05-15</date>
    <date>2019-06-15</date>
    <date>2019-07-15</date>
    <date>2019-08-15</date>
    <date>2019-09-15</date>
    <date>2019-10-15</date>
    <date>2019-11-15</date>
    <date>2019-12-15</date>
    <date>2020-01-15</date>
    <date>2020-02-15</date>
    <date>2020-03-15</date>
</input>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/input">
    <output>
        <xsl:for-each select="date">
            <end-of-last-month date=".">
                <xsl:call-template name="end-of-last-month">
                    <xsl:with-param name="date" select="."/>
                </xsl:call-template>
            </end-of-last-month>
        </xsl:for-each>
    </output>
</xsl:template>

<xsl:template name="end-of-last-month">
    <xsl:param name="date"/>
    <!-- extract date components -->
    <xsl:variable name="year" select="substring($date, 1, 4)"/>
    <xsl:variable name="month" select="substring($date, 6, 2)"/>
    <!-- go one month back -->
    <xsl:variable name="y" select="$year - ($month = 1)"/>
    <xsl:variable name="m" select="($month + 10) mod 12 + 1"/>
    <!-- get month length -->
    <xsl:variable name="cal" select="'312831303130313130313031'"/>
    <xsl:variable name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
    <xsl:variable name="month-length" select="substring($cal, 2*($m - 1) + 1, 2) + ($m=2 and $leap)" />
    <!-- output -->
    <xsl:value-of select="$y" />
    <xsl:value-of select="format-number($m, '-00')" />
    <xsl:text>-</xsl:text>
    <xsl:value-of select="$month-length" />
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <end-of-last-month date="2019-01-15">2018-12-31</end-of-last-month>
   <end-of-last-month date="2019-02-15">2019-01-31</end-of-last-month>
   <end-of-last-month date="2019-03-15">2019-02-28</end-of-last-month>
   <end-of-last-month date="2019-04-15">2019-03-31</end-of-last-month>
   <end-of-last-month date="2019-05-15">2019-04-30</end-of-last-month>
   <end-of-last-month date="2019-06-15">2019-05-31</end-of-last-month>
   <end-of-last-month date="2019-07-15">2019-06-30</end-of-last-month>
   <end-of-last-month date="2019-08-15">2019-07-31</end-of-last-month>
   <end-of-last-month date="2019-09-15">2019-08-31</end-of-last-month>
   <end-of-last-month date="2019-10-15">2019-09-30</end-of-last-month>
   <end-of-last-month date="2019-11-15">2019-10-31</end-of-last-month>
   <end-of-last-month date="2019-12-15">2019-11-30</end-of-last-month>
   <end-of-last-month date="2020-01-15">2019-12-31</end-of-last-month>
   <end-of-last-month date="2020-02-15">2020-01-31</end-of-last-month>
   <end-of-last-month date="2020-03-15">2020-02-29</end-of-last-month>
</output>

演示:https://xsltfiddle.liberty-development.net/94AbWB5

【讨论】:

【参考方案2】:

如果您有权访问 XPath 2.0 日期/时间库,

(1) 转换为xs:date

<xsl:variable name="d" select="xs:date($in)"/>

(2) 提取月份中的某天:

<xsl:variable name="dom" select="day-from-date($d)"/>

(3) 从日期中减去这个天数:

<xsl:variable name="result" select="$d - xs:dayTimeDuration('P1D') * $dom"/>

【讨论】:

我不喜欢这样做。

以上是关于SOA 转换中的 XSLT 映射以获取上个月的最大日期的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的 XSLT 转换 - 如何获取包含文档的有效 URL?

使用 XSLT 将 XML 转换为 CSV,用于在单个标记中以空格分隔的多个记录

如何使用 XSLT 2.0 获取当前日期时间的 RFC1123 日期格式

使用 xslt 获取位于另一个路径中的另一个 xml 值

XSLT 映射以删除内部具有 PIPE 分隔符号的双引号

是否可以将 XSLT 转换应用于 DOM 元素?