如何在一组同名元素中查找特定字符串

How to find specific string within a group of like-named elements

对于下面的 XML,如果有多个选举,我如何找到每个员工选择了哪个选举,以及最新日期。如果所有选举都说 'Waive' 或当该员工没有选举时,将使用默认值 'Bronze'。

示例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>

我尝试了一些操作,例如在 Elections/Election 标签上使用 for-each 查找字符串“(Gold Membership) (Elect)”和“(Silver Membership) (Elect)”并设置如果找到但没有用,则为变量。

所需的输出为:

荷马、辛普森、青铜
玛姬、辛普森、金
丽莎、辛普森、金
巴特、辛普森、青铜
爷爷、辛普森、银

工作量很大。

如果每个员工只有一次标记为 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}).*', '')" 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\).*', '')" /> 
            </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