根据条件XSLT 2.0获取日期列表

时间:2018-11-21 18:48:43

标签: xml xslt text xslt-2.0

我有这种情况,其中:

  1. 如果wd:F03_First_Start等于0并且wd:F03_Last_Day小于或等于wd:End_Date,请获取从wd:First_Daywd:F03_Last_Day的日期< / p>

  2. 如果wd:F03_First_Start等于0并且wd:F03_Last_Day大于wd:End_Date,请获取从wd:First_Daywd:End_Date的日期

  3. 如果wd:F03_First_Start等于1并且wd:F03_Last_Day小于或等于wd:End_Date,请获取从wd:Start_Datewd:F03_Last_Day的日期< / p>

  4. 如果wd:F03_First_Start等于1并且wd:F03_Last_Day大于wd:End_Date,请获取从wd:Start_Datewd:End_Date的日期

此外,每个日期还需要根据其所处的日期获得另一个值。如果它是星期五的09年9月11日(dd-MM-yyyy)(法语中的vendredi),则应从wd:F01_vendredi中获取值。

供参考: 伦迪(星期一) 狂欢节(星期二) Mercredi(星期三) jeudi(星期四) vendredi(星期五) samedi(星期六) dimanche(星期日)

这是XML:

<wd:Report_Data xmlns:wd="urn:com.report/F03">
    <wd:Report_Entry>
        <wd:ID>00000001</wd:ID>
        <wd:LOA>
            <wd:Type>XYZ</wd:Type>
            <wd:First_Day>09-11-2018</wd:First_Day>
            <wd:F03_First_Day>vendredi</wd:F03_First_Day>
            <wd:F03_Last_Day>12-11-2018</wd:F03_Last_Day>
            <wd:F03_Last>lundi</wd:F03_Last>
            <wd:F03_First_Start>0</wd:F03_First_Start>
        </wd:LOA>
        <wd:F01_lundi>1</wd:F01_lundi>
        <wd:F01_mardi>2</wd:F01_mardi>
        <wd:F01_mercredi>3</wd:F01_mercredi>
        <wd:F01_jeudi>4</wd:F01_jeudi>
        <wd:F01_vendredi>5</wd:F01_vendredi>
        <wd:F01_samedi>6</wd:F01_samedi>
        <wd:F01_dimanche>7</wd:F01_dimanche>
        <wd:Start_Date>01-11-2018</wd:Start_Date>
        <wd:F03_Start_Day>jeudi</wd:F03_Start_Day>
        <wd:End_Date>30-11-2018</wd:End_Date>
        <wd:F03_End_Day>vendredi</wd:F03_End_Day>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:ID>00000002</wd:ID>
        <wd:LOA>
            <wd:Type>ABC</wd:Type>
            <wd:First_Day>25-06-2018</wd:First_Day>
            <wd:F03_First_Day>lundi</wd:F03_First_Day>
            <wd:F03_Last_Day>03-12-2018</wd:F03_Last_Day>
            <wd:F03_Last>lundi</wd:F03_Last>
            <wd:F03_First_Start>1</wd:F03_First_Start>
        </wd:LOA>
        <wd:F01_lundi>6</wd:F01_lundi>
        <wd:F01_mardi>5</wd:F01_mardi>
        <wd:F01_mercredi>4</wd:F01_mercredi>
        <wd:F01_jeudi>3</wd:F01_jeudi>
        <wd:F01_vendredi>2</wd:F01_vendredi>
        <wd:F01_samedi>1</wd:F01_samedi>
        <wd:F01_dimanche>0</wd:F01_dimanche>
        <wd:Start_Date>01-11-2018</wd:Start_Date>
        <wd:F03_Start_Day>jeudi</wd:F03_Start_Day>
        <wd:End_Date>30-11-2018</wd:End_Date>
        <wd:F03_End_Day>vendredi</wd:F03_End_Day>
    </wd:Report_Entry>
</wd:Report_Data>

我想要的输出是:

00000001;09-11-2018;XYZ;5
00000001;10-11-2018;XYZ;6
00000001;11-11-2018;XYZ;7
00000001;12-11-2018;XYZ;1
00000002;01-11-2018;ABC;3
00000002;02-11-2018;ABC;2
...
...
...
00000002;30-11-2018;ABC;2

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以创建一个从日期格式创建XSLT / XPath xs:date的函数,然后可以为您的条件设置模板并处理日期,这是第一个条件的示例:< / p>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="urn:com.report/F03"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:param name="month-names" as="xs:string+"
        select="'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'"/>

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:function name="mf:createDate" as="xs:date">
        <xsl:param name="date" as="xs:string"/>
        <xsl:sequence select="xs:date(replace($date, '([0-9]{2})-([0-9]{2})-([0-9]{4})', '$3-$2-$1'))"/>
    </xsl:function>

    <xsl:template match="Report_Entry[LOA/F03_First_Start = 0 and mf:createDate(LOA/F03_Last_Day) le mf:createDate(End_Date)]">
        <xsl:apply-templates select="." mode="date">
            <xsl:with-param name="date" select="mf:createDate(LOA/First_Day)"/>
            <xsl:with-param name="last-date" select="mf:createDate(LOA/F03_Last_Day)"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="Report_Entry" mode="date">
        <xsl:param name="date"/>
        <xsl:param name="last-date"/>
        <xsl:value-of select="ID, format-date($date, '[D01]-[M01]-[Y0001]'), LOA/Type, *[local-name() = 'F01_' || lower-case(format-date($date, '[F]', 'fr', 'AD', 'FR'))]" separator=";"/>
        <xsl:text>&#10;</xsl:text>
        <xsl:variable name="next-date" select="($date + xs:dayTimeDuration('P1D'))[. le $last-date]"/>
        <xsl:apply-templates select=".[exists($next-date)]" mode="date">
            <xsl:with-param name="date" select="$next-date"/>
            <xsl:with-param name="last-date" select="$last-date"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

请注意,这需要使用像Saxon PE或EE这样的XSLT 3处理器来支持使用fr函数,例如,直接从xs:date提取format-date法国工作日名称。 '[F]','fr',不幸的是,Saxon的HE版本不支持此功能,在那里您会获得英文名称或英文工作日编号,因此对于HE来说,您可以尝试

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="urn:com.report/F03"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:param name="month-names" as="xs:string+"
        select="'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'"/>

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:function name="mf:createDate" as="xs:date">
        <xsl:param name="date" as="xs:string"/>
        <xsl:sequence select="xs:date(replace($date, '([0-9]{2})-([0-9]{2})-([0-9]{4})', '$3-$2-$1'))"/>
    </xsl:function>

    <xsl:template match="Report_Entry[LOA/F03_First_Start = 0 and mf:createDate(LOA/F03_Last_Day) le mf:createDate(End_Date)]">
        <xsl:apply-templates select="." mode="date">
            <xsl:with-param name="date" select="mf:createDate(LOA/First_Day)"/>
            <xsl:with-param name="last-date" select="mf:createDate(LOA/F03_Last_Day)"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="Report_Entry" mode="date">
        <xsl:param name="date"/>
        <xsl:param name="last-date"/>
        <xsl:value-of select="ID, format-date($date, '[D01]-[M01]-[Y0001]'), LOA/Type, *[local-name() = 'F01_' || $month-names[xs:integer(format-date($date, '[F1]', 'en', (), ()))]]" separator=";"/>
        <xsl:text>&#10;</xsl:text>
        <xsl:variable name="next-date" select="($date + xs:dayTimeDuration('P1D'))[. le $last-date]"/>
        <xsl:apply-templates select=".[exists($next-date)]" mode="date">
            <xsl:with-param name="date" select="$next-date"/>
            <xsl:with-param name="last-date" select="$last-date"/>
        </xsl:apply-templates>
    </xsl:template>

</xsl:stylesheet>

示例https://xsltfiddle.liberty-development.net/nc4NzRr/1。对于XSLT 2,您可能需要将对||字符串连接运算符的使用替换为对concat函数的调用:http://xsltransform.hikmatu.com/nc4NzPV