泉州V23网络为您的企业打造精品网站:  800元起"网站建设+精美网页设计+搜索引擎推广"服务!! 7*24咨询:13559567956
网站建设客户中心联系我们网站地图
 
V23首页网站制作网站推广域名空间付款方式联系我们
网站建设相关文章

如何匹配特定的节点

当使用<xsl:template>元素时,通常要使用match属性,来指明该模板规则是同哪个元素相匹配的,要应用于哪个元素。match属性支持一套复杂的语法,来精确的定位哪些元素是匹配的,哪些是不匹配的。另外,用于xsl:apply-templates,xsl:value-of,xsl:for-each,xsl:copy-of以及xsl:sort等元素中的select属性,也是用来定位匹配元素的,它支持比match属性更复杂、强大的语法功能集来精确定位元素。下面就分几个部分,来详细的讲述一下如何实现匹配特定的节点。 
根节点的匹配: 

当用xsl样式表对xml文档进行转换时,转换的结果是一个well-formed的xml文档,因此,xsl转换所做的第一项工作就是生成结果文档的根元素。通常,xsl样式表都是从匹配根节点的规则开始,来生成结果文档的根元素。为了表示一条规则是同根节点相匹配的,可以给match属性赋值"/"。例如: 

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

这条规则仅仅匹配xml文档的根节点。当xml文档的根节点被xsl处理器读入时,就输出标记<result_tree_root>,然后去处理根节点的子元素,最后输出</result_tree_root>节点。 

一般的xsl处理器都有一个缺省的同根节点相匹配的规则,因此在平时所见到的xsl实例中可能没有根规则。而上面这个小例子,则覆盖了根节点的缺省规则,使用了自定义的根规则。 

下面用一个只有一个根规则的,完整的样式表的例子,来加深一下对上述描述的认识。 

对于一个xml文档,如果施以下面的样式表: 

<?xml version="1.0" encoding="gb2312" ?><xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> 

<xsl:template match="/"> <html> <head> <title>An XSL style sheet with one rule for the root node</title> </head> <body> Hello everyone! This is a rule for the root node of the input document. </body> </html></xsl:template>
因为在这个样式表中,只提供了应用于根节点的规则,而且在这条规则中没有指明如何进一步的去处理根节点的子节点。所以,在转换后的输出结果中,只有这条规则中的内容。换句话说,这个样式表无论施加在哪个xml文档上,都会得到下面的输出结果: 

<html> <head> <title> An XSL style sheet with one rule for the root node</title> </head> <body> Hello everyone! This is a rule for the root node of the input document. </body></html>


你可以自己写一个well-formed的xml文档,然后应用上面的样式表,看看会得到什么转换效果。 然后再把这个样式表施加到其它的xml文档中试试呢? 

元素匹配: 

在xsl样式表中,最基本的模式匹配就是元素匹配。在元素匹配中,match属性的值是一个元素名,所有叫那个名字的元素都将被匹配。例如,下面的模板匹配所有的book元素,并且用黑体来显示它的子元素author: 

<xsl:template match="book"> <b><xsl:value-of select="author"/></b></xsl:template>
为了能更详细的解释说明如何实现"元素匹配",我们来看一个具体的例子。在这个例子中,我们用样式表book.xsl来对xml文档book.xml进行转换。 

对于下面的book.xml文档: 

<?xml version="1.0" encoding="gb2312" ?><?xml:stylesheet type="text/xsl" href="book.xsl" ?><books> <book> <title>ASP2.0揭密</title> <author>Stephen Walther</author> </book> 

<book> <title>LINUX大全</title> <author>Jack Tachett Jr. And David Gunter</author> </book></books> 

给定的样式表book.xsl如下: 

<?xml version="1.0" encoding="gb2312"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> 

<xsl:template match="/"> <html> <head> <title>书目列表</title> </head> <body> <xsl:apply-templates select="books"/> </body> </html></xsl:template> 

<xsl:template match="books"> <h1 align="center">书目列表</h1> <table border="1" align="center"> <th>书名</th> <th>作者</th> <xsl:apply-templates select="book" /> </table></xsl:template> 

<xsl:template match="book"> <tr> <td aligh="center"><xsl:value-of select="title" /></td> <td aligh="center"><xsl:value-of select="author" /></td> </tr></xsl:template> 

</xsl:stylesheet> 

在这个样式表中,首先通过match="/"来匹配根节点。在根节点的模板规则中,包含了一个xsl:apply-templates元素,xsl:apply-templates利用select属性来保证根节点的子节点books元素将被进一步处理。 

然后,通过match="books"创建了一个应用于books元素的规则。这条规则首先生成了一个表格的头部信息,然后又通过xsl:apply-templates指出,需要对book元素再做进一步的处理来生成表格的内容。 

最后,通过match="books"创建了book规则。在book规则中,通过<xsl:value-of select="title" />和<xsl:value-of select="author" />来获取book元素中的子元素title和author的实际内容,并把这些内容封装在html的<tr>、<td>元素中,因此,最终得到的结果就是一个显示书目信息的表格,如下图所示: 




用 / 来匹配子节点: 

如第一部分所讲,单独使用"/"符号表示匹配根节点。然而,如果在两个元素名之间使用"/"符号,则表示第二个元素是第一个元素的子元素。例如,仍然利用上一节中的xml文档实例book.xml,book/title所指的就是book元素中的title子元素。 

利用"/",可以更精确的匹配某种类型的元素。举个例子来说,对于下面的一段xml文档: 

<entertainment> <book> <title>书名</title> </book> <film> <title>电影名</title> </film></entertainment> 

如果只利用元素名title来匹配元素,则无论是book元素中title的还是film元素中的title都将得到匹配。如果只想对book元素中的title进行样式设定那该怎么办呢?利用"/"符号,就可以达到这个目的,如下所示: 

<xsl:template match="book/title"> <b><xsl:value-of select="."/></b></xsl:template>
注意:上面这条规则匹配的是book元素的子元素title,而不是有子元素title的book元素。换句话说,在<xsl:value-of select="."/>中的"."指的是title元素,而不是book元素。 

利用"/",还可以达到更深层次的匹配。例如,entertainment/book/title,表示匹配title元素,这个title的父元素是book,book的父元素是entertainment。 

最后还要说明一点:在由"/"形成的匹配的层次结构中,还可以利用通配符"*"来表示任意的元素。例如,下面的规则表示要应用于所有的祖父元素是entertainment的title元素。 

<xsl:template match=" entertainment/*/title"> <b><xsl:value-of select="."/></b></xsl:template>


用 // 来匹配后代节点: 


有时候,可能需要匹配某个元素的所有后代元素中的某类特定节点,例如对于下面的一段xml代码: 

<toolbar> <name>工具条</name></toolbar>
<menu> <name>菜单</name> <submenu> <name>子菜单</name> <submenu> <name>子菜单的子菜单</name> </submenu> </submenu></menu>

在上面这段代码中,toolbar中有name元素,menu中也有name元素作为直接子元素,menu的其它子元素中又有name作为子元素。如果想对menu元素的所有后代元素中的name元素应用某种规则,无论是通过元素名进行元素匹配还是利用"/"进行层次匹配,实现起来都不十分方便。 

要想通过一种方便简洁的方式实现上述目的,可以利用"//"符号。"//"表示某元素的所有后代元素,而不管这个后代元素是直接子元素,还是子子元素等等(也就是说,不管后代元素的深度有多深)。 

利用"//"来设定menu的后代中的name的应用规则,可以用如下方式: 

<xsl:template match="menu//name"> <b><xsl:value-of select="." /></b></xsl:template>
如果在某应用规则中直接以"//"打头进行匹配,则表示匹配根节点的所有某类后代元素。例如,下面的规则将对所有的name元素进行处理,而不管name位于什么位置。 

<xsl:template match="//name"> <b><xsl:value-of select="." /></b></xsl:template>
由本小节中的讲解可以看出,"/"是用来匹配直接子元素中的某类元素,"//"是用来匹配所有后代子元素中的某类元素。"/"的定位更精确,"//"的定位更广泛、灵活。