2012-05-25 42 views
2

我遇到了麻烦,在寻找一个准确,简单,回答这个问题的SO或其他地方:XSL处理顺序

在XSL文件,你怎么知道哪个模板将首先处理,第二,等?我读到它是按XPath的特定顺序排列的。另外,XSL 1.0与2.0有区别吗?

最后,这里是我正在玩弄的一个有缺陷的XSL文件。目前输出只是标题“目录”。我也会在这里附上XML。

<xsl:template match="/"> 
    <h1> 
     <xsl:text>Table of Contents</xsl:text> 
    </h1> 
</xsl:template> 

<xsl:template match="heading1"> 
    <h2> 
     <xsl:value-of select="."/> 
    </h2> 
</xsl:template> 

<p> 
    <xsl:text>This document contains </xsl:text> 
    <xsl:value-of select="count(/article/body/heading1)"/> 
    <xsl:text> chapters. </xsl:text> 
</p> 

和XML:

<article> 
<title> 
    Creating output 
</title> 
<body> 
    <heading1>Generating text</heading1> 
    <heading1>Numbering things</heading1> 
    <heading1>Formatting numbers</heading1> 
    <heading1>Copying nodes from the input document to the output</heading1> 
    <heading1>Handling whitespace</heading1> 
</body> 

任何解释为什么所有没有被显示的内容?感谢您的帮助!

回答

4

这里发生的事情:

  1. 的XSLT处理器读取你的XML的根元素
  2. 然后它会在样式表,看看有什么相匹配。它找到你的第一个模板
  3. 它执行第一个模板。
  4. 第一个模板表示输出文本,然后什么都不做,所以XSLT处理器移动到下一个输入元素....但是你已经处理了整个根节点,所以没有更多的输入节点在同一级别。完成。

您需要做的是在第一个模板中放置一个<xsl:apply-templates/>。当处理器遇到这种情况时,它重新开始,但是这次上下文是根内的第二级节点列表。它会依次查看每个XML节点,在样式表中找到最匹配的模板并执行它。

这是一个关键概念 - 模板不受控制,也不是程序性的。

+0

非常有趣!我忘记了XSLT的性质。在什么时候我需要使用xsl:apply-templates?当然,我不会在每个深度将它胡椒粉涂抹一遍。 (鉴于一个更大的文件) – BlackVegetable

+2

其实,是的,你这样做。这种递归调用技术被称为“推送”处理,因为您让XSLT处理器将数据“推送”到您的模板。这是处理器工作的自然方式,所以精心设计的样式表将与“apply-templates”“拼凑起来”。另一种方法是在“嵌套”for-each和“call-template”的情况下使用“pull”风格,但如果您欣赏拉式处理的力量,那就很不自然。 –

+1

答案的这一点是错误的:“所以XSLT处理器移动到下一个输入元素”。不,它不;它只通过使用xsl:apply-templates进入你要求的地方。 –