xslt中的apply-template和call-template的区别

来源:互联网 发布:怎么制作京东秒杀软件 编辑:程序博客网 时间:2024/05/22 17:36

xslt中的apply-template和call-template的区别

在使用xslt进行xml内容转化时会经常用到两种方式调用template,即apply-template和call-template,关于这俩种的用法的区别通过在网上查找到的资料跟大家共同学习参考一下。

首先,在 XSLT 中,您需要注意 XSL 转换过程上下文节点的更动。 XSL 转换上下文节点是当前被 XSLT 处理引擎处理的 XML 文档中的节点。 
   “apply-templates”元素会更改 XSL 转换中的上下文节点,使其移动到匹配“select”属性选出的 XML 节点,调用相应的 XSLT 模板规则处理该 XML 节点。而“call-template”元素不更改 XSL 转换上下文节点,因此,被“call-template”调用的具名模板处理的 XML 节点,依然是“call-template”元素所在模板规则所处理的 XML 节点。 
  
其次,还需要注意转换过程中 XSLT 处理流程和当前模板规则的变动。 在 XSLT 文档中,每个“template”元素称为一个模板规则。特殊地,具有“name”属性的“template”元素,称为“具名模板”。 
   “apply-templates”节点由“select”属性选出 XML 节点后,对这些节点分别调用最匹配的 XSLT 模板规则进行转换处理,例如“apply-templates select="p|h1"”,将选出 XML 文档中的“p”和“h1”元素进行 XSL 转换,这时,XSLT 文档可能指定“template match="p"”模板处理选中的“p”元素,而另外指定“template match="h1"”处理选中的“h1”元素。因此,XSLT 处理器在遇到该“apply-templates”元素后,处理流程会跳转到不同的模板,分别处理相应的 XML 节点。而“call-template”则简单得多。XSLT 处理器在遇到“call-template name="template"”指令后,通常就会将处理流程直接跳转到“template name="template"”的具名模板。 

关于“apply-templates”匹配在使用时还有比如apply-templates select="Hotels",而在对应的xsl中找不到对应的template match="Hotels"

但是有template match="Hotel",其中Hotel是Hotels的子节点,这种情况下就会匹配到template match="Hotel"中,去做具体执行。Hotels有多少个Hotel子节点就会执行该模板规则多少次。

再次,你可以在“apply-templates”指令中指定“mode”属性,指示模板规则的模式。如“apply-templates select="*" mode="title"”,将指示 XSLT 处理器使用具有“mode="title"”的模板规则处理匹配的 XML 节点。而在使用“call-template”指令时,你不能指定模式。 

下表是对“call-template”,“apply-templates”和“for-each”三个所做对比

对比项

 apply-templates

call-template

for-each 

改变XML上下文节点

改变XSLT当前模板

处理节点集内每个节点

仅处理当前节点

可传递参数

可排序

在使用模式匹配时可以参考以下语法:

模式匹配的语法不光可以在<xsl:template>元素的match属性中使用,还可以在<xsl:apply-templates>、<xsl:value-of>、<xsl:for-each>、<xsl:copy-of>、<xsl:sort>、<xsl:variable>和<xsl:param>元素的select属性中使用。

 

下面列出常用的模式匹配的用法:

 

1、匹配根节点

例如:<xsl:template match="/">,表示匹配根节点。

 

2、匹配元素节点

例如:<xsl:template match="employees">,表示匹配employees元素节点。

 

3、使用通配符

例如:<xsl:template match="*">,表示匹配任何元素。

 

4、使用@匹配属性

用@加上数姓名,可以用于匹配属性节点。

例如:<xsl:template match="@mode">,表示匹配mode属性节点。不过要注意的是,XSLT处理器在遍历节点的树状结构时,并不处理属性节点。如果要让处理器处理属性节点,必须显式调用<xsl:apply-templates>元素,并使用select属性选择属性节点。

 

还可以将@与星号(*)一起使用,例如:<xsl:template match="@*">,表示匹配任意的属性节点。

 

5、使用斜杠(/)匹配子节点

例如:<xsl:template match="employees/employee">,表示匹配employees元素节点下的任意的employee子节点。

 

6、使用双斜杠(//)匹配后代节点

有时候,希望对某一类元素节点进行处理,而不管该节点在树状结构中所处的位置,就可以使用双斜杠(//)来匹配节点。例如:<xsl:template match="//name">,表示匹配根节点下任意的name元素节点,而不管该节点所处的位置。例如:<xsl:template match="employees//name">,表示匹配employees元素节点下的任意的name元素节点。

 

7、使用或操作符(|)

使用或操作符(|)来可选择地匹配多个节点。例如:<xsl:template match="name|age">,表示匹配任意的name或age元素节点。

例如:<xsl:template match="employee/name!monthly_pay/@mode">,表示匹配employee元素节点下的任意name子节点,或monthly_pay元素节点的mode属性节点。

 

8、使用[]操作符

可以在[]中指定布尔表达式,用于在节点集中更精确地匹配某一个节点。

例如:如果只想匹配第一个employee元素,可以这样写:<xsl:template match="employee[1]">,表示匹配第一个employee子元素节点。这和上面的写法是等价的:

<xsl:template match="employee[position()=1]">

position()是一个函数调用,返回节点在上下文中的当前位置,然后判断该位置是否等于1.

 

9、使用node()匹配节点

node()表示匹配除属性节点和根节点之外的其他任何节点。

例如:<xsl:template match="node()">.

 

10、使用text()匹配文本节点

text()表示匹配任意的文本节点,例如:<xsl:template match="text()">。

 

11、使用processing-instruction()匹配处理指令

processing-instruction()表示匹配任的处理指令节点。

例如:<xsl:tempate match="processing-instruction()">。processing-instruction()还可以带一个参数,用于指定处理指令目标的名字,这样,只有和这个名字相同的处理指令才能被匹配。

 

12、使用comment()匹配注释

comment()表示匹配任意的注释节点,例如:<xsl:template match="comment()">。

 

13、使用id()进行匹配

一个ID类型的属性唯一标识了XML文档中的一个元素。

例如:<xsl:template match="id('E-2001320001')">表示匹配拥有ID类型属性并且其值等于E-2001320001的元素。要注意的是,要让这种方式能够工作,必须在源XML文档的DTD中声明ID类型的属性,可以是内部的或外部的DTD,如果源文档那个没有DTD,则id()函数就不能正常工作。

以上内容供大家在以后开发中参考

0 0
原创粉丝点击