2014-06-05 148 views
0

我有以下模板,嵌套循环。该模板生成多个xml文件的页码(例如:20个文件=我书中的章节)。编号从@ start = 4开始。 $ pagenr是页面计数器。为了更有效地计数,我将前一个文件的页数保存在$ prevPage中。然后我只需在内部循环中添加xml文件中的页数。 问题:它真的能像那样工作吗?或者是在内部循环中更新了$ prevPage计数? 当处理内循环中的指令时,我看到XMLSpy调试器跳出内循环到<xsl:variable name="prevPage" ....行。在嵌套循环中计数:效率更高?

<xsl:template match="lat:numberGroup"> 
<xsl:variable name="start" select="@start"/> 
<xsl:variable name="format" select="@format"/> 
<!-- newnav.xml must not be processed here, as it is being created --> 
<xsl:for-each select="lat:entry[not(@pagenr) or not(@pagenr = 'no')]"> 
    <xsl:variable name="prevPage" select="number($start) + count((preceding-sibling::node())/document(lat:file)//lat:page)"/> 
    <xsl:variable name="actFile" select="lat:file"/> 
    <xsl:for-each select="document($actFile)//lat:page"> 
     <li> 
      <a> 
       <xsl:variable name="pagenr" select="number($prevPage) + count(./preceding::lat:page )"/> 
       <xsl:attribute name="href"> 
         <xsl:value-of select="tokenize($actFile,'\.')[1]"/> 
         .xhtml#pg 
         <xsl:value-of select="$pagenr"/> 
       </xsl:attribute> 
       <xsl:number value="$pagenr" format="{$format}"/> 
      </a> 
     </li> 
    </xsl:for-each> 
</xsl:for-each> 
</xsl:template> 
+0

*跳回*可能是由XSLT处理器的延迟评估引起的。但是,由于XSLT *变量*只设置一次,之后永远不会改变,随后的任何后续跳回可能仅表明懒惰,并不代表实际的重新计算。 –

+0

[我如何计算XSLT执行时间到毫秒级精度?](http://stackoverflow.com/questions/8783696/how-do-i-time-my-xslt-execution-times-to-millisecond -准确性) –

回答

0

它在内部的工作原理取决于您使用的XSLT处理器。然而,如果处理器采用的策略效率低于明显的策略,那就是在发生变量声明的位置评估变量,那么您就会非常失败。正如Marcus Rickert所说,你可能会看到处理器试图做得比这更好,通过推迟对变量的评估直到需要为止(例如,如果内部循环执行零次,根本不需要)。

顺便说一句,表达式tokenize($actFile,'\.')[1]也可以在内部循环之外进行评估。一个智能处理器会为你做这种优化,但如果你想确定,你可以通过创建另一个变量手工完成。