Как найти указанную c строку в группе одноименных элементов - PullRequest
0 голосов
/ 14 февраля 2020

Для XML ниже, как мне узнать, какие выборы, с последней датой, если избрано несколько выборов, выбрал каждый сотрудник. Значение по умолчанию «Бронза» будет использоваться, если на всех выборах будет указано «Отказ» или если нет выбора для этого сотрудника.

Пример XML:

<Data>
    <Employee>
            <First_Name>Homer</First_Name>
            <Last_Name>Simpson</<Last_Name>
            <Elections>
                <Election type="Homer Simpson on 01/01/2020 (Gold Membership) (Waive)"/>
            </Elections>
            <Elections>
                <Election type="Homer Simpson on 01/01/2020 (Silver Membership) (Waive)"/>
            </Elections>
    </Employee>
    <Employee>
            <First_Name>Marge</First_Name>
            <Last_Name>Simpson</<Last_Name>
            <Elections>
                <Election type="Marge Simpson on 01/01/2020 (Gold Membership) (Waive)"/>
            </Elections>
            <Elections>
                <Election type="Marge Simpson on 01/03/2020 (Gold Membership) (Elect)"/>
            </Elections>
            <Elections>
                <Election type="Marge Simpson on 01/03/2020 (Silver Membership) (Waive)"/>
            </Elections>
    </Employee>
    <Employee>
            <First_Name>Lisa</First_Name>
            <Last_Name>Simpson</<Last_Name>
            <Elections>
                <Election type="Lisa Simpson on 01/01/2020 (Gold Membership) (Elect)"/>
            </Elections>
            <Elections>
                <Election type="Lisa Simpson on 01/01/2020 (Silver Membership) (Waive)"/>
            </Elections>
    </Employee>
    <Employee>
            <First_Name>Bart</First_Name>
            <Last_Name>Simpson</<Last_Name>
            <Elections>
                <Election type="Bart Simpson on 01/01/2020 (Gold Membership) (Waive)"/>
            </Elections>
            <Elections>
                <Election type="Bart Simpson on 01/01/2020 (Silver Membership) (Waive)"/>
            </Elections>
            <Elections>
                <Election type="Bart Simpson on 01/01/2020 (Bronze Membership) (Elect)"/>
            </Elections>
    </Employee>
    <Employee>
            <First_Name>Maggie</First_Name>
            <Last_Name>Simpson</<Last_Name>
            <Elections>
                <Election type="Lisa Simpson on 01/01/2020 (Silver Membership) (Elect)"/>
            </Elections>
            <Elections>
                <Election type="Lisa Simpson on 01/01/2020 (Gold Membership) (Waive)"/>
            </Elections>
    </Employee>
    <Employee>
            <First_Name>Grandpa</First_Name>
            <Last_Name>Simpson</<Last_Name>
    </Employee>
</Data>

Я попытался несколько вещей, таких как for-each над тегом Elections / Election, ищущих строку «(Золотое членство) (Elect)» и «(Серебряное членство) (Elect)» и устанавливающих переменную, если она была найдена, но это не Работа.

Желаемый результат будет:

Гомер, Симпсон, Бронза
Мардж, Симпсон, Золото
Лиза, Симпсон, Золото
Барт, Симпсон, Бронза
Дедушка, Симпсон, Серебро

1 Ответ

0 голосов
/ 16 февраля 2020

Это много работы.

Было бы значительно проще, если бы у каждого работника было только одно избрание, помеченное как Elect. Но вы говорите, что их может быть больше одного, и что нужно учитывать только самое последнее. И что еще хуже, вы используете формат даты, который нельзя использовать для сортировки как есть.

Попробуйте что-то вроде следующего:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:template match="/Data">
    <xsl:for-each select="Employee">
        <!-- names -->
        <xsl:value-of select="First_Name" /> 
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Last_Name" /> 
        <xsl:text>,</xsl:text> 
        <!-- membership -->
        <xsl:variable name="valid-elections" select="Elections/Election[contains(@type, '(Elect)')]"/>      
        <xsl:choose>
            <xsl:when test="$valid-elections">
                <xsl:variable name="memberships" as="element()*">
                    <xsl:perform-sort>
                        <!-- sort by reformatted date -->
                        <xsl:sort select="replace(@type, '.*(\d{2})/(\d{2})/(\d{4}).*', '$3$1$2')" order="descending"/>
                        <xsl:sequence select="$valid-elections"/>
                    </xsl:perform-sort>
                </xsl:variable> 
                <!-- extract type from latest membership -->
                <xsl:value-of select="replace($memberships[1]/@type, '.*\((Gold|Silver|Bronze) Membership\).*', '$1')" /> 
            </xsl:when>
            <xsl:otherwise>Bronze</xsl:otherwise>
        </xsl:choose>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Демо : https://xsltfiddle.liberty-development.net/gWEaSvj

...