xslt匹配过滤结果集的前x项

时间:2011-02-21 15:28:29

标签: xml xslt umbraco

xslt相当新,请原谅我这是一个基本问题 - 我无论是在SO上还是在Google上搜索都找不到答案。

我要做的是返回一组经过筛选的节点,然后在该集合中的前1或2项上进行模板匹配,另一个模板与剩余项匹配。但是,如果没有<xsl:for-each />循环,我似乎无法做到这一点(这是非常不受欢迎的,因为我可能匹配3000个节点而只是区别对待1个。)

使用position()不起作用,因为它不受过滤影响。我已经尝试对结果集进行排序,但这似乎没有及早生效以影响模板匹配。 <xsl:number />输出正确的数字,但我不能在匹配语句中使用它们。

我在下面放了一些示例代码。我正在使用下面不适合的position()方法来说明问题。

提前致谢!

XML:

<?xml version="1.0" encoding="utf-8"?>
<news>
    <newsItem id="1">
        <title>Title 1</title>
    </newsItem>
    <newsItem id="2">
        <title>Title 2</title>
    </newsItem>
    <newsItem id="3">
        <title></title>
    </newsItem>
    <newsItem id="4">
        <title></title>
    </newsItem>
    <newsItem id="5">
        <title>Title 5</title>
    </newsItem>
</news>

XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <ol>
            <xsl:apply-templates select="/news/newsItem [string(title)]" />
        </ol>
    </xsl:template>

    <xsl:template match="newsItem [position() &lt; 4]">
        <li>
            <xsl:value-of select="title"/>
        </li>
    </xsl:template>

    <xsl:template match="*" />
</xsl:stylesheet>

期望的结果:

  1. Title 1
  2. Title 2
  3. Title 5

1 个答案:

答案 0 :(得分:6)

这个实际上比你想象的要简单。做:

 <xsl:template match="newsItem[string(title)][position() &lt; 4]">

<xsl:apply-templates选择中删除[string(title)]谓词。

像这样:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <ol>
            <xsl:apply-templates select="/news/newsItem" />
        </ol>
    </xsl:template>

    <xsl:template match="newsItem[string(title)][position() &lt; 4]">
        <li><xsl:value-of select="position()" />
            <xsl:value-of select="title"/>
        </li>
    </xsl:template>

    <xsl:template match="*" />
</xsl:stylesheet>

您在这里实际做的是在[position() &lt; 4]过滤器之后应用第二个过滤器([string(title)]),这会导致position()应用于过滤后的列表。