我目前有类似于以下XML的内容:
<div class="newsFeed">
<div class="newsItem"><news position="3"/></div>
<categoryFilter dayFilter="4">
<div class="newsItem"><news position="2"/></div>
</categoryFilter>
</div>
我需要复制XML,并在节点上输出第n个新闻项。此外,我需要能够过滤该新闻。对于此示例,让我们按如下方式构建我的新闻:
<xsl:variable name="news">
<xsl:for-each select="1 to 30">
<item>
<day><xsl:value-of select=". mod 4" /></day>
<content>Content: <xsl:value-of select="." /></content>
</item>
</xsl:for-each>
</xsl:variable>
我实际上使用document()
并使用for-each对其进行排序,但我试图保持简洁。这意味着我的输出XML将类似于以下内容:
<div class="newsFeed">
<div class="newsItem">Content: 3</div>
<div class="newsItem">Content: 8</div>
</div>
第二个8
的原因是因为categoryFilter会过滤掉每天<item>
的日期不是4
(恰好是第4天,第8天,第12天) ,依此类推),然后我们选择第二个。
产生上述内容的XSLT如下:
XSLT:
<xsl:template match="news">
<xsl:param name="items" select="$news" />
<xsl:variable name="position" select="@position" />
<xsl:copy-of select="$items/item[position()=$position]/content" />
</xsl:template>
<xsl:template match="categoryFilter">
<xsl:param name="items" select="$news" />
<xsl:variable name="day" select="@dayFilter" />
<xsl:variable name="filteredItems">
<xsl:for-each select="$items/item[day=$day]">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:variable>
<xsl:apply-templates>
<xsl:with-param name="items" select="$filteredItems">
</xsl:apply-templates>
</xsl:template>
我的问题在于<for-each>
。我必须使用for-each来过滤掉<item>
节点,这似乎很愚蠢,但我无法找到更好的方法。只需执行<xsl:variable select="$items/item[day=$day]">
即可更改结构,并使其<xsl:template match="news">
无法正常工作。
有没有办法过滤掉子节点而不使用for-each?我正在使用<xsl:stylesheet version="3.0">
答案 0 :(得分:1)
而不是这样做......
<xsl:variable name="filteredItems">
<xsl:for-each select="$items/item[day=$day]">
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:variable>
...你可以使用一个序列。这将选择实际项目,而不是创建它们的副本
<xsl:variable name="filteredItems">
<xsl:sequence select="$items/item[day=$day]" />
</xsl:variable>
这样做,$filteredItems/item
仍然有用。
或者,您可以采取相反的方法,并且不需要在所有表达式中指定/item
。
首先,定义您的news
变量,如下所示:
<xsl:variable name="news" as="element()*">
这意味着您可以像这样编写使用它的表达式:
<xsl:copy-of select="$news[position()=$position]/content" />
同样适用于filteredItems
....
<xsl:variable name="filteredItems" select="$items[day=$day]" />