http://www.w3schools.com/xsl/xsl_apply_templates.asp
对于这些陈述,
<xsl:template match="/"> <html> <body> <h2>My CD Collection</h2> <xsl:apply-templates/> </body> </html> </xsl:template>
我的困惑是,
(1)< xsl:apply-templates />的功能是什么?它不包含任何要调用的特定模板。我认为它会匹配(返回)所有直接的子元素当前元素(当前节点的非直接子节点不会被返回,当前节点是根节点),不知道我是否正确?
(2)在(1)中返回所有匹配节点之后,XSLT处理器的下一步将是什么?
(3)在这个特定的例子中,根节点是目录还是另一个更高的根?为什么?
提前致谢,
乔治
首先,节点和元素是不一样的。元素是节点,但节点不一定是元素。你经常会发现人们可以互换使用这个术语。 XML中实际上有四种节点:元素,文本节点,处理指令和注释。 (属性不是真正的节点,我会在一秒钟内得到)
在XSLT中,XML文档的根不是其顶级元素;根是一个真正不存在的抽象。顶层元素是根的子节点。例如,这里是一个格式正确的XML文档,其根有五个子节点,包括顶级元素:
<?xml-stylesheet href="mystyle.css" type="text/css"?> <!-- this is a perfectly legitimate XML document --> <top_level_element/>
五?看起来只有三个。我想我会让你弄清楚其他两个是你自己。提示:在该示例中实际上可能有七个节点。
XPath表达式/查找文档根,而不是顶级元素。在上述情况下,要找到顶级元素,您可以使用/ top_level_ement或/ *。 (使用/ *查找顶级元素总是安全的,因为文档根目录必须有一个元素。)
所以掌握了这些知识,让我们看看apply-templates是如何做的。它基本上执行两个步骤:首先,它构建一组节点。然后,对于每个模板,它找到匹配的模板(从XSLT文件中的模板中)并将模板应用于该模板。正如您在其中一条意见中所观察到的,它在概念上与循环非常相似。
第一步使用select属性。它提供了一个XPath表达式,用于构建将应用模板的节点集。如果没有提供select属性,则它构建的列表是上下文节点的所有子节点。 (“上下文节点”是当前模板应用于的节点。)
第二步使用模板元素上的匹配属性。样式表处理器查找其匹配属性与其尝试应用模板的节点匹配的所有模板。如果它发现多于一个,它会选择最特定的一个,例如。给出这些模板:
<xsl:template match="*"/> <xsl:template match="foo"/> <xsl:template match="foo[bar]"/>
具有bar子元素的foo元素将被第三个匹配,没有bar的foo元素将被第二个匹配,并且baz元素将被匹配。 (XSLT使用的实际方法定义为here;实际上,我已经使用XSLT将近十年,我从来没有一次需要知道它是如何工作的,虽然这很有趣)
如果没有找到匹配项,它将使用内置的默认模板作为节点类型 – 基本上,您可以假设任何XSLT转换都隐含包含这些模板:
<xsl:template match="*"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"> <xsl:copy/> </xsl:template> <xsl:template match="processing-instruction() | comment() | @*"/>
掌握所有这些知识,您现在可以了解身份转换:
<xsl:template match="node() | @*"> <xsl:copy> <xsl:apply-templates select="node() | @*"/> </xsl:copy> </xsl:template>
它匹配任何节点或属性(请注意,属性不是节点,这就是为什么需要@ *),将其复制,然后将模板应用于其所有子节点和属性。 (只有文档根和元素将具有子节点,并且只有元素将具有属性。)由于它是变换中唯一的模板,并且它匹配所有节点和属性,因此它将自身应用于所有子节点和属性。因此,它将源树中的所有内容复制到输出树。
如果将此模板添加到标识变换中:
<xsl:template match="foo"/>
你现在有一个转换,除了foo元素之外的源树中的每个节点 – 第二个模板匹配foo元素(第一个也是,因为第二个匹配属性更具体,这是XSLT选择的),并且什么都不做跟他们。
鉴于所有这些,您的具体问题的答案:
>< xsl:apply-templates>将模板应用于上下文节点的子节点。>匹配节点在步骤1中不“返回”; XSLT处理器为每个XSLT处理器找到一个模板并应用它。>在这个例子中,上下文节点是文档根,一个抽象节点,顶层元素以及其外的注释或处理指令是其子节点。