Использование position () в XSLT для получения нескольких узлов с одинаковым именем - PullRequest
0 голосов
/ 04 августа 2020

Я пытаюсь преобразовать некоторые XML данные в csv с желаемым результатом:

"0000001"|"2020-06-18"
"0000001"|"2020-06-17"
"0000001"|"2020-06-16"
"0000001"|"2020-06-15"
"0000001"|"2020-06-14"
"0000001"|"2020-07-02"
"0000001"|"2020-07-01"
"0000001"|"2020-06-30"
"0000001"|"2020-06-29"
"0000001"|"2020-06-28"

Но вместо этого я сейчас получаю:

"0000001"|"2020-06-18"
"0000001"|"2020-06-17"
"0000001"|"2020-06-16"
"0000001"|"2020-06-15"
"0000001"|"2020-06-14"
"0000001"|"2020-06-18"
"0000001"|"2020-06-17"
"0000001"|"2020-06-16"
"0000001"|"2020-06-15"
"0000001"|"2020-06-14"

XML, с которым я работаю, имеет следующий формат:

<wd:Report_Data>
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>0000001</wd:Employee_ID>
        </wd:Worker>
        <wd:Time_Off_Event>
            <wd:Time_Off_Date wd:Descriptor="18-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="17-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="16-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="15-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="14-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>0000001</wd:Employee_ID>
        </wd:Worker>
        <wd:Time_Off_Event>             
            <wd:Time_Off_Date wd:Descriptor="02-Jul-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="01-Jul-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="30-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="29-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="28-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
        </wd:Time_Off_Event>
    </wd:Report_Entry>
</wd:Report_Data>

Фрагмент XSLT, касающийся получения даты, которую я написал до сих пор:

<xsl:template match="wd:Report_Data/wd:Report_Entry">    
<xsl:variable name="root" select="."/>              
                    <xsl:for-each select="wd:Time_Off_Event/wd:Time_Off_Date">
                        <xsl:variable name="count" select="position()"/>
                        <Record xtt:separator="|" xtt:quotes="always" etv:incrementNumber="recordCount" xtt:quoteStyle="double">                    
                            <Employee_ID xtt:required="true" xtt:maxLength="7">
                                <xsl:value-of select="$root/wd:Worker/wd:Employee_ID"/>
                            </Employee_ID>

                            <Date xtt:required="true" xtt:maxLength="10">
                                <xsl:variable name="day" select="substring((//wd:Time_Off_Date/@wd:Descriptor)[$count],1,2)"/>
                                <xsl:variable name="month" select="substring((//wd:Time_Off_Date/@wd:Descriptor)[$count],4,3)"/>
                                <xsl:variable name="year" select="substring((//wd:Time_Off_Date/@wd:Descriptor)[$count],8,4)"/>
                                <xsl:variable name="monthConversion" select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', $month)) div 3 + 1" />
                                <xsl:variable name="mthNum" select="format-number($monthConversion, '00')" />                                                       
                                <xsl:variable name="timeOffDate" select="concat($year,'-',$mthNum,'-',$day)"/>
                                <xsl:value-of select="$timeOffDate"/>
                            </Date>                         
                        </Record>
                    </xsl:for-each> 
</xsl:template>

Я довольно нуб XSLT, так что извиняюсь, если вы хотите удариться головой о стол при виде вышеизложенного:)

Моя первоначальная мысль заключается в том, что это связано с использованием мной position () - I ' m не на 100%, как это работает, поэтому любой ввод будет оценен.

1 Ответ

0 голосов
/ 04 августа 2020

Рассмотрим следующий упрощенный пример:

XML

<wd:Report_Data xmlns:wd="some/wd/namespace">
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>0000001</wd:Employee_ID>
        </wd:Worker>
        <wd:Time_Off_Event>
            <wd:Time_Off_Date wd:Descriptor="18-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="17-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="16-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="15-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="14-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
        </wd:Time_Off_Event>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>0000002</wd:Employee_ID>
        </wd:Worker>
        <wd:Time_Off_Event>             
            <wd:Time_Off_Date wd:Descriptor="02-Jul-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="01-Jul-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="30-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="29-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
            <wd:Time_Off_Date wd:Descriptor="28-Jun-2020 - 1 Day">
            </wd:Time_Off_Date>
        </wd:Time_Off_Event>
    </wd:Report_Entry>
</wd:Report_Data>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wd="some/wd/namespace"
exclude-result-prefixes="wd">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/wd:Report_Data">
    <xsl:for-each select="wd:Report_Entry">
        <xsl:variable name="empID" select="wd:Worker/wd:Employee_ID" />
        <xsl:for-each select="wd:Time_Off_Event/wd:Time_Off_Date">
            <xsl:text>"</xsl:text>
            <xsl:value-of select="$empID"/>
            <xsl:text>"|"</xsl:text>
            <xsl:value-of select="substring(@wd:Descriptor, 8, 4)"/>
            <xsl:text>-</xsl:text>
            <xsl:variable name="mmm" select="substring(@wd:Descriptor, 4, 3)"/>
            <xsl:variable name="m" select="string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', $mmm)) div 3 + 1" />
            <xsl:value-of select="format-number($m, '00')" />
            <xsl:text>-</xsl:text>
            <xsl:value-of select="substring(@wd:Descriptor, 1, 2)"/>
            <xsl:text>"&#10;</xsl:text>
        </xsl:for-each> 
    </xsl:for-each> 
</xsl:template>

</xsl:stylesheet>

Результат

"0000001"|"2020-06-18"
"0000001"|"2020-06-17"
"0000001"|"2020-06-16"
"0000001"|"2020-06-15"
"0000001"|"2020-06-14"
"0000002"|"2020-07-02"
"0000002"|"2020-07-01"
"0000002"|"2020-06-30"
"0000002"|"2020-06-29"
"0000002"|"2020-06-28"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...