XSLT 应用模板问题 [英] XSLT apply-template question

查看:26
本文介绍了XSLT 应用模板问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 XSLT apply-template 语句感到困惑.例如,在 w3school.

I am confused about XSLT apply-template statement. For example, here in w3school.

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)的作用是什么?它不包含任何要调用的特定模板.我认为它会匹配(返回)当前元素的所有直接子节点(不会返回当前节点的非直接子节点,当前节点是根节点),不确定我是否正确?

(1) what is the function of <xsl:apply-templates/>? It does not contain any specific template to call. I think it will match (return) all directly child of current element (non-direct child of current node will not be returned, current node is root node), not sure whether I am correct?

(2) 在(1)中返回所有匹配的节点后,下一步XSLT处理器会做什么?

(2) after all matched nodes are returned in (1), what are the next step XSLT processor will do?

(3) 在这个特定的示例中,根节点是目录还是另一个更高级别的根?为什么?

(3) in this specifc sample, the root node is catalog or another higher level of root? and why?

提前致谢,乔治

推荐答案

一些让你更容易理解答案的事情:

Some things that will make understanding the answers you get easier:

首先,节点和元素不是一回事.元素是节点,但节点不一定是元素.您经常会发现人们交替使用这些术语.XML 中实际上有四种节点:元素、文本节点、处理指令和注释.(属性并不是真正的节点,我稍后会讲到.)

First and foremost, nodes and elements are not the same thing. Elements are nodes, but nodes aren't necessarily elements. You often find people using the terms interchangeably. There are actually four kinds of nodes in XML: elements, text nodes, processing instructions, and comments. (Attributes aren't really nodes, which I'll get to in a second.)

在 XSLT 中,XML 文档的根不是它的顶级元素;根是一个实际上并不存在的抽象.顶级元素是根的子元素.例如,这里有一个格式良好的 XML 文档,其根有五个子节点,包括顶级元素:

In XSLT, the root of an XML document isn't its top-level element; the root is an abstraction that doesn't really exist. The top-level element is a child of the root. For instance, here's a well-formed XML document whose root has five child nodes, including the top-level element:

<?xml-stylesheet href="mystyle.css" type="text/css"?>
<!-- this is a perfectly legitimate XML document -->
<top_level_element/>

五个?好像只有三个.我想我会让你自己弄清楚另外两个是什么.提示:在该示例中实际上可能有 七个 节点.

Five? It looks like there are only three. I think I'll let you figure out what the other two are yourself. Hint: there could actually be seven nodes in that example.

XPath 表达式 / 查找文档根,而不是顶级元素.在上述情况下,要查找顶级元素,您可以使用 /top_level_element/*.(使用 /* 来查找顶级元素总是安全的,因为文档根必须有一个子元素.)

The XPath expression / finds the document root, not the top-level element. In the above case, to find the top-level element, you'd use /top_level_element, or /*. (It's always safe to use /* to find the top-level element, since the document root must have a single element child.)

有了这些知识,让我们看看 apply-templates 做了什么.它基本上执行两步过程:首先,它构建一组节点.然后,对于每个模板,它都会找到一个匹配的模板(从 XSLT 文件中的模板中)并将该模板应用到它.正如您在其中一条评论中所观察到的,它在概念上与循环非常相似.

So armed with that knowledge, let's look at what apply-templates does. It basically performs a two-step process: First, it builds a set of nodes. Then, and for each one, it finds a matching template (from among the templates in the XSLT file) and applies the template to it. As you observed in one of your comments, it's conceptually very similar to a loop.

select 属性用于第一步.它提供了一个 XPath 表达式,用于构建它将应用模板的节点集.如果没有提供 select 属性,它构建的列表是上下文节点的所有子节点.(上下文节点"是应用当前模板的节点.)

The select attribute is used in the first step. It provides an XPath expression that's used to build the node set that it's going to apply templates to. If no select attribute is provided, the list it builds is all children of the context node. (The "context node" is the node that the current template is being applied to.)

template 元素上的 match 属性用于第二步.样式表处理器查找所有 match 属性与其试图应用模板的节点相匹配的模板.如果找到多个,它会选择最具体的一个,例如鉴于这些模板:

The match attribute on the template elements is used in the second step. The stylesheet processor finds all templates whose match attribute matches the node it's trying to apply templates to. If it finds more than one, it selects the most specific one it can, e.g. given these templates:

<xsl:template match="*"/>
<xsl:template match="foo"/>
<xsl:template match="foo[bar]"/>

一个带有 bar 子元素的 foo 元素将被第三个匹配,一个没有 barfoo 元素code> 将被第二个匹配,而 baz 元素将被第一个匹配.(XSLT 使用的实际方法定义在这里;实际上,我一直在使用XSLT 使用了近十年,我从来没有需要具体了解它是如何工作的,尽管它很有趣.)

a foo element with a bar child element will be matched by the third, a foo element with no bar will be matched by the second, and a baz element will be matched by the first. (The actual method that XSLT uses is defined here; in practice, I've been using XSLT for nearly a decade and I've never once needed to know specifically how it works, though it's interesting.)

如果它没有找到匹配项,它将使用节点类型的内置默认模板 - 基本上,您可以假设任何 XSLT 转换都隐式包含这些模板:

If it doesn't find a match, it will use the built-in default template for the type of node - basically, you can assume that any XSLT transform implicitly contains these templates:

<xsl:template match="*">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="text()">
    <xsl:copy/>
</xsl:template>

<xsl:template match="processing-instruction() | comment() | @*"/>

有了所有这些知识,您现在可以理解身份转换:

Armed with all this knowledge, you can now understand the identity transform:

<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
</xsl:template>

匹配任何节点或属性(注意,属性不是节点,这就是需要 @* 的原因),复制它,然后将模板应用于其所有子节点和属性.(只有文档根和元素有子节点,只有元素有属性.)因为它是转换中的唯一模板,它匹配所有节点和属性,所以它适用于所有子节点和属性.因此,它将源树中的所有内容复制到输出树中.

That matches any node or attribute (note that attributes aren't nodes, which is why @* is needed), copies it, and then applies templates to all of its child nodes and attributes. (Only the document root and elements will have child nodes, and only elements will have attributes.) Since it's the only template in the transform, and it matches all nodes and attributes, it applies itself to all of the child nodes and attributes. Thus, it copies everything in the source tree to the output tree.

如果您将此模板添加到标识转换:

If you add this template to the identify transform:

<xsl:template match="foo"/>

您现在有一个转换,可以复制源树中的每个节点 除了 foo 元素 - 第二个模板匹配 foo 元素(第一个一个也是如此,但由于第二个的 match 属性更具体,所以它是 XSLT 选择的一个)并且对它们没有任何作用.

you now have a transform that copies every node in the source tree except foo elements - that second template matches foo elements (the first one does too, but since the second one's match attribute is more specific, it's the one XSLT chooses) and does nothing with them.

综上所述,您的具体问题的答案:

Given all that, the answers to your specific questions:

  1. 将模板应用于上下文节点的子节点.

  1. <xsl:apply-templates> applies templates to the children of the context node.

匹配的节点不会在步骤 1 中返回";XSLT 处理器为每一个找到一个模板并应用它.

Matched nodes aren't "returned" in step 1; the XSLT processor finds a template for each and applies it.

在这个例子中,上下文节点是文档根,一个抽象节点,顶级元素和它之外的任何评论或处理指令都是其子节点.

In this example, the context node is the document root, an abstract node that the top-level element and any comments or processing instructions outside it are the children of.

这篇关于XSLT 应用模板问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆