将 XML 条记录组合成有意义的句子:"Dale, Harry and Lucy"

Combining XML records into meaningful sentence: "Dale, Harry and Lucy"

假设我在 XML

中有这个
<people>
    <name>Dale</name>
    <name>Harry</name>
    <name>Lucy</name>
</people>

我该如何将其转换为

Dale, Harry and Lucy

只使用 XSLT?它必须在一定程度上具有灵活性,以便在 name 多的地方,它仍然有意义。

Dale, Harry, Lucy, James, Andy, Shelly and Norma

这个问题与this question非常相似,但不完全相同。您唯一需要添加的是确定何时插入 and 的第二个条件。

XML 输入

<people>
    <name>Dale</name>
    <name>Harry</name>
    <name>Lucy</name>
    <name>John</name>
</people>

样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text"/>

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

    <xsl:template match="name">
        <xsl:variable name="pos" select="position()"/>

        <xsl:if test="$pos = last() and $pos != 1">
            <xsl:text> and </xsl:text>
        </xsl:if>

        <xsl:value-of select="."/>

        <xsl:if test="$pos != last() and $pos + 1 != last()">
            <xsl:text>, </xsl:text>
        </xsl:if>
    </xsl:template>

</xsl:transform>

文本输出

Dale, Harry, Lucy and John

或者,如果您更喜欢神秘代码,但行数较少,则可以使用单个 XPath 表达式 (XSLT 1.0) 完成:

<xsl:template match="name">    
    <xsl:value-of select="concat(.,
    substring(', ', 3 - ((position() != last() and position() + 1 != last()) * 2)),
    substring(' and ', 6 - ((position() = last() - 1) * 5)))"/>
</xsl:template>

尝试:

<xsl:template match="/people">
    <xsl:for-each select="name">
        <xsl:value-of select="."/>
        <xsl:choose>
            <xsl:when test="position()=last() - 1"> and </xsl:when>
            <xsl:when test="position()!=last()">, </xsl:when>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>