Получить список дат на основе условия XSLT 2.0 - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть такой сценарий, в котором:

  1. , если wd:F03_First_Start равно 0, а wd:F03_Last_Day меньше или равно wd:End_Date, получить даты из wd:First_Dayдо wd:F03_Last_Day

  2. , если wd:F03_First_Start равно 0 и wd:F03_Last_Day больше wd:End_Date, получить даты от wd:First_Day до wd:End_Date

  3. , если wd:F03_First_Start равно 1, а wd:F03_Last_Day меньше или равно wd:End_Date, получить даты от wd:Start_Date до wd:F03_Last_Day

  4. , если wd:F03_First_Start равно 1, а wd:F03_Last_Day больше wd:End_Date, получить даты от wd:Start_Date до wd:End_Date

Кроме того, для каждой даты требуетсячтобы получить другое значение в зависимости от того, какой день они.Если это 09-11-2018 (дд-мм-гггг), то есть пятница (по-французски vendredi), он должен получить значение из wd:F01_vendredi.

Для справки: lundi (понедельник) mardi (вторник)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 голосов
/ 22 ноября 2018

Вы можете создать функцию для создания XSLT / XPath xs:date из вашего формата даты, затем вы можете настроить шаблоны для ваших условий и обработать даты, вот пример для первого из ваших условий:

<?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>

Обратите внимание, что для этого требуется процессор XSLT 3, такой как Saxon PE или EE, для поддержки извлечения названия дня французской недели fr непосредственно из xs:date с использованием функции format-date с помощью, например, '[F]',' fr ', к сожалению, версия 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...