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

发布于 2024-10-18 13:16:02 字数 1881 浏览 3 评论 0 原文

对 xslt 很陌生,所以如果这是一个基本问题,请原谅我 - 我无法在 SO 上或通过 Google 搜索找到答案。

我想要做的是返回一组经过过滤的节点,然后对该组中的前 1 或 2 个项目进行模板匹配,然后另一个模板与其余项目匹配。但是,如果没有 循环,我似乎无法做到这一点(这是非常不可取的,因为我可能匹配 3000 个节点,但只以不同方式处理 1 个节点) 。

使用 position() 不起作用,因为它不受过滤的影响。我尝试过对结果集进行排序,但这似乎没有足够早地生效以影响模板匹配。 输出正确的数字,但我无法在匹配语句中使用这些数字。

我在下面放置了一些示例代码。我使用下面不合适的 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. 标题 1
  2. 标题 2
  3. 标题 5

Quite new to xslt so forgive me if this is a basic question - I can't find the answer either on SO or by searching on Google.

What I am trying to do is return a filtered set of nodes and then have a template match on the first 1 or 2 items in that set and another template match the remainder. However I don't seem to be able to do this without a <xsl:for-each /> loop (which is highly undesirable as I may be matching 3000 nodes and only treating 1 differently).

Using position() doesn't work as this is unaffected by the filtering. I've tried sorting the result set but this doesn't seem to take effect early enough to affect the template match. The <xsl:number /> outputs the correct numbers but I can't use these in a match statement.

I've put some example code below. I'm using the unsuitable position() method below to illustrate the problem.

Thanks in advance!

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() < 4]">
        <li>
            <xsl:value-of select="title"/>
        </li>
    </xsl:template>

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

Desired Result:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

压抑⊿情绪 2024-10-25 13:16:02

这实际上比你想象的要简单。执行:

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

并从 选择中删除 [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() < 4]">
        <li><xsl:value-of select="position()" />
            <xsl:value-of select="title"/>
        </li>
    </xsl:template>

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

您在这里有效执行的是在 [string(title)] 过滤器之后应用第二个过滤器 ([position() < 4]) ,这会导致将 position() 应用于过滤后的列表。

This one's actually simpler than you might think. Do:

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

And drop the [string(title)] predicate from your <xsl:apply-templates select.

Like this:

<?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() < 4]">
        <li><xsl:value-of select="position()" />
            <xsl:value-of select="title"/>
        </li>
    </xsl:template>

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

What you're effectively doing here is applying a second filter ([position() < 4]) after your [string(title)] filter, which results in the position() being applied to the filtered list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文