如何避免结果中的最后一个分页元素:
<pages>
<page title="Manchuria"/>
<page-break/>
<page title="Zombie Librarian"/>
<page-break/>
<page title="Perfect the first time"/>
<page-break/>
</pages>
给定以下源xml:
<articles>
<article id="az401" title="The Long Goodbye" publishable="true" version="3">
<original>
<article id="aw301" version="1"/>
</original>
<edits>
<article id="az401" version="3"/>
<article id="pe814" version="2"/>
<article id="we453" version="4"/>
</edits>
</article>
<article id="yu475" title="Manchuria" publishable="true" version="4">
<original>
<article id="xc141" version="1"/>
</original>
<edits>
<article id="er111" version="2"/>
<article id="yu475" version="4"/>
<article id="iu931" version="3"/>
</edits>
</article>
<article id="nb741" title="Zombie Librarian" publishable="true" version="2">
<original>
<article id="nc441" version="1"/>
</original>
<edits>
<article id="nb741" version="2"/>
</edits>
</article>
<article id="ww555" title="Perfect the first time" publishable="true" version="1">
<original>
<article id="ww555" version="1"/>
</original>
<edits/>
</article>
<article id="kl922" title="Here we go again" publishable="true" version="1">
<original>
<article id="kl922" version="1"/>
</original>
<edits>
<article id="uy541" version="2"/>
</edits>
</article>
</articles>
以及以下xslt代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:key name="article-by-id" match="article" use="@id"/>
<xsl:template match="/">
<pages>
<xsl:apply-templates select="/articles/article[@publishable='true']" mode="subfilter"/>
</pages>
</xsl:template>
<xsl:template match="article" mode="subfilter">
<xsl:variable name="id_of_latest_edit">
<xsl:for-each select="edits/article">
<xsl:sort data-type="number" select="@version"/>
<xsl:if test="position()=last()"><xsl:value-of select="@id"/></xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="is_latest_edit" select="@id = key('article-by-id',$id_of_latest_edit)/@id"/>
<xsl:variable name="has_no_edits" select="not(edits/article)"/>
<xsl:if test="$is_latest_edit or $has_no_edits">
<xsl:apply-templates select="self::article" mode="layout">
<xsl:with-param name="is_last_page" select="position()=last()"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
<xsl:template match="article" mode="layout">
<xsl:param name="is_last_page"/>
<page title="{@title}"/>
<xsl:if test="not($is_last_page)">
<page-break/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
钞票
- 问题是使用了一个额外的模板来进一步过滤原始节点集,从而使position((不再可靠
- 使用<xsl:with-param name="is_first_page;select=";position((=1"/>也不适用于示例xml
如果不能通过使用谓词直接过滤项目,那么可以使用变量来保存过滤集。然后对结果使用position()
函数将正确工作:
XSLT 1.0(+EXSLT node-set((函数(
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<pages>
<xsl:variable name="pages">
<xsl:apply-templates select="/articles/article[@publishable='true']" mode="subfilter"/>
</xsl:variable>
<xsl:apply-templates select="exsl:node-set($pages)/article"/>
</pages>
</xsl:template>
<xsl:template match="article" mode="subfilter">
<xsl:variable name="id_of_latest_edit">
<xsl:for-each select="edits/article">
<xsl:sort data-type="number" select="@version"/>
<xsl:if test="position()=last()">
<xsl:value-of select="@id"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="@id = $id_of_latest_edit or not(edits/article)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
<xsl:template match="article">
<page title="{@title}"/>
<xsl:if test="position()!=last()">
<page-break/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>