XML到CSV(使用输入日期生成新日期)

问题描述 投票:0回答:1

我有一个要求,我必须从记录中的日期(YYYYMMDD)生成新的日期(YYYYMMDD),下面是新日期创建的逻辑:

1.如果'MM - 1'= 0,则生成MM -'12',年份值为YearFromActualDate - 1 2.DD始终为'01'3。如果'MM - 1'!= 0,则输出MM将是'MM - 1'和Year将保持不变我提到的预期输出将提供上述逻辑的概念。请指教。

        <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:fn="http://www.w3.org/2005/xpath-functions" >
<xsl:output method="text" encoding="utf-8" />
<xsl:param name="delim" select="','" />
<xsl:param name="quote" select="'&quot;'" />
<xsl:param name="break" select="'&#xA;'" />
<xsl:template match="/">
    <xsl:value-of select="$quote" />
    <xsl:text>Name</xsl:text>
    <xsl:value-of select="$quote" />
    <xsl:value-of select="$delim" /> 
    <xsl:value-of select="$quote" />
    <xsl:text>Date</xsl:text>
    <xsl:value-of select="$quote" />
    <xsl:value-of select="$delim" />
    <xsl:value-of select="$quote" />
    <xsl:text>NewDate</xsl:text>
    <xsl:value-of select="$quote" />
    <xsl:value-of select="$break" /> 
    <xsl:apply-templates select="ID/ED/E1" /> 
</xsl:template>
<xsl:template match="E1">
    <xsl:value-of select="$quote" />
    <xsl:value-of select="name"/>
    <xsl:value-of select="$quote" />
    <xsl:value-of select="$delim" />   
    <xsl:value-of select="$quote" />
    <xsl:value-of select="date"/>
    <xsl:value-of select="$quote" />
    <xsl:value-of select="$delim" />  
    <xsl:value-of select="$quote" />
    <xsl:variable name="newdate" select="'01'" />
    <xsl:variable name="inMonth" select="substring(date,5,2)" />
    <xsl:variable name="inputYear" select="substring(date,1,4)" />
    <xsl:choose>
        <xsl:when test = "$inMonth='01'">
            <xsl:variable name="calculatedMonth" select="12"/>
            <xsl:value-of select="concat(xs:integer($inputYear) - 1,$calculatedMonth,$newdate)" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="inMonthlength" select="string-length(xs:string(xs:integer($inMonth) - 1))" />
            <xsl:if test="xs:integer($inMonthlength) !=2">
                <xsl:value-of select="concat($inputYear,concat(0,xs:integer($inMonth) - 1),$newdate)" />
            </xsl:if>
            <xsl:if test="xs:integer($inMonthlength) =2">
                <xsl:value-of select="concat($inputYear,(xs:integer($inMonth) - 1),$newdate)" />
            </xsl:if>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:value-of select="$quote"/>
    <xsl:if test="following-sibling::*">
        <xsl:value-of select="$break" />    
    </xsl:if>
</xsl:template>

输入:

   <ID>
   <ED>
   <E1>
   <name>Eva</name>
   <date>20190504</date> (Consider date as YYYYMMDD)
   </E1>
   <E1>
   <name>Alan</name>
   <date>20190101</date>
   </E1>
   </ED>
   <ID>

预期产出:

     "Name","Date","NewDate"
     "Eva","20190504","20190401"
     "Alan","20190101","20181201"
xslt-2.0
1个回答
0
投票

如果我正确地反向设计你的算法,你想要的是上个月的第一天。

逻辑上步骤是:

  1. 将您的日期转换为xs:date值
  2. 在当月的第一天
  3. 减去一个月。

在实践中,最简单的是将(1)和(2)结合起来,以便最终得到

xs:date(replace($date, '(....)(..)(..)', '$1-$2-01')) - xs:yearMonthDuration('P1M')

然后您可以使用此格式将此日期格式化为YYYYMMDD

format-date($date, '[Y0001][M01][D01]')
© www.soinside.com 2019 - 2024. All rights reserved.