xslt 学习笔记
1.什么是xsl
xsl(eXtensible Stylesheet Language)—可扩展样式表语言,主要用于将一个xml文档转换为另外的文档(xml文档,html文档),以及定义转换后文档的显示外观。
xsl包括3种语言:
xsl转换语言(XSL Transformations, xslt),主要将一个xml文档转换为其他的xml文档或其他类型的文档;
xml 路径语言(XPath)
XPath主要在XSLT和XPointer中使用,用于识别,选择,匹配xml文档中各个组成部分,包括元素,属性,文本内容等等
xsl格式化对象(XSL-FO),定义了许多的xml标记,这些标记描述了应如何显示内容。
2.xslt
xml将数据与显示分开
,xml文档用于表示数据,xslt控制显示。
下面看一个例子:
xml如下:
<?xml-stylesheet type="text/xsl" href="welcome.xsl"?>
<欢迎词>
<标题>welcome</标题>
<内容>hello,world!</内容>
</欢迎词>
在xml声明之后的处理指令,表示该xml文档关联了一个xslt样式表文档welcome.xsl。IE浏览器内嵌的xml处理器在分析这个文档的时候,会调用相应的xslt处理器对该文档进行转换。
下面给出welcome.xsl:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="欢迎词">
<head>
<title>
<xsl:value-of select="标题"/>
</title>
</head>
<body>
<xsl:value-of select="内容"/>
</body>
</xsl:template>
</xsl:stylesheet>
xslt是基于xml的语言,这意味着xslt文档本身也是格式良好的xml文档。<xsl:stylesheet>是xslt文档的根元素,xslt处理器将xml文档作为一棵树来操作,xml文档的各个组成部分作为树中的节点。
文档树的根称为根节点。注意:根节点不是根元素。根结点是根元素的父节点。为“/”
welcome.xml的树状结构如下:
3.模板规则
xslt样式表由一组模板规则(template rules)组成。模板规则包含了两个部分:模式(pattern)和模板(template)。模式用于在源文档树中匹配(定位)节点,模板定义节点的处理规则,通过模板的实例化来组成结果树的一部分。
当xslt处理器使用xslt样式表转换xml文档时,处理器将遍历xml文档的树状结构,依次浏览每个节点,并将浏览的节点与样式表中的每个模板规则的模式进行比较。如果处理器找到了与模板规则的模式相匹配的节点,处理器就会输出此规则的模板。
每个模板规则都是一个<xsl:template>元素,规则的模式由属性match来指定,元素的内容是用于组成结果树的模板。在模板中,可以包含xslt的指令,这些指令都是由xslt名称空间中的元素来执行的。在xslt名称空间中的元素,都要加上xsl前缀,没有xsl前缀的元素,将被直接输出作为结果树的一部分。
例:employee.xml
<?xml-stylesheet type="text/xsl" href="src/employee.xsl"?>
<employees>
<employee sn="E-200402100001">
<name>zhangsan</name>
<age>25</age>
<monthly_pay mode="cash">
1200.00
</monthly_pay>
</employee>
<employee sn="E-200402100006">
<name>lisi</name>
<age>28</age>
<monthly_pay mode="cash">
1600.00
</monthly_pay>
</employee>
<employee sn="E-200503220001">
<name>wangwu</name>
<age>30</age>
<monthly_pay mode="credit_card">
3500.00
</monthly_pay>
</employee>
</employees>
employee.xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>employees info</title>
</head>
</html>
</xsl:template>
</xsl:stylesheet>
输出:
<head>
<title>employees info</title>
</head>
</html>
当xslt处理器处理到xml文档的根结点时,与样式表中的模板规则匹配,正好匹配了一个模板规则,于是输出上面的标签,上面的例子只对根结点进行了处理,如果要让处理器对根及诶但的子节点进行处理,可以使用<xsl:apply-templates>
4.<xsl:apply-templates>元素
<xsl:apply-templates>元素告诉处理器处理当前节点的所有子节点。在匹配的节点模板中还可以再包含<xsl:apply-templates>元素,从而通知处理器处理该节点的所有子节点,这样依次调用,就可以完成对文档树中所有节点处理。
5.<xsl:value-of>元素
<xsl:value-of>元素用于在结果树中创建一个文本节点。<xsl:value-of>元素有一个必须的属性select,用于指定要计算的表达式,表达式的计算结果将被转换为一个字符串值,用这个字符串值来创建一个文本节点。如果字符串为空,那么文本节点将不会创建
我们一起来看一个例子:
这个xsl也是对employee.xml处理
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head></head>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="employees">
<body>
<table border="1">
<xsl:apply-templates/>
</table>
</body>
</xsl:template>
<xsl:template match="employee">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="age"/></td>
<td><xsl:value-of select="monthly_pay"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
下面我们来看看上面的xml处理时,xslt处理器都做了什么:
1). 将根结点与样式表中的所有模板规则进行比较,结果与第一个模板规则匹配。
2). 输出<html>和<head></head>标签。
3). <xsl:apply-templates/>元素通知处理器对根结点的所有子节点进行处理。
A. 将根结点的第一个子节点(xml-stylesheet节点)与模板规则进行比较,没有找到匹配的模板规则,不产生任何输出。
B. 将根结点的第二个子节点(<employees>根元素节点)与模板规则进行比较,结果与第二个模板规则匹配。
C. 输出<body>和<table border=”1”>标签。
D. <xsl:apply-templates/>元素通知处理器对employees节点的所有子节点进行处理。
a) 将employees节点的第一个子节点(<employees>下的第一个子元素<employee>)
b) 与模板规则进行比较,结果与第三个模板规则匹配。
c) 输出<tr>标签
d) 输出<td>标签,然后由<xsl:value-of select=”name”/>元素取出<employee>的子元素<name>的内容,作为文本节点输出到结果树中,接着输出</td>标签。
e) 相同方式输出age和monthly_pay
f) 输出</tr>标签
g) 将employees节点的第二个和第三个子节点与模板规则比较,结果与第三个模板规则匹配。重复b-f。
E. 输出</table>和</body>标签。
4). 输出</html>标签。处理完成。
6.<xsl:for-each>元素
<xsl:for-each>元素有一个必须的属性select,用于指定一个表达式,该表达式计算的结果必须是一个节点集。<xsl:for-each>元素用于在一个节点集中一次选取每一个节点。被选择的节点作为当前节点,所有被选择节点的列表作为当前节点列表。<xsl:for-each>元素的内容是一个模板,对于每一个被选择的节点,实例化该模板。
下面我们使用<xsl:for-each>元素改写上面的例子:
他们的效果是一样的
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head></head>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="employees">
<body>
<table border="1">
<xsl:for-each select="employee">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="age"/></td>
<td><xsl:value-of select="monthly_pay"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</xsl:template>
</xsl:stylesheet>