本节将举例学习如何用XSL将XML转换成HTML。这个举例的细节将在下一节中解释。
XSLT命令[xml格式转换]
1.循环 <xsl:for-each...>
<xsl:for-each select="BookList/Item">
<tr>
<th align="left"> <xsl:value-of select=".//title" /></th>
<td><xsl:value-of select=".//categroy" /></td>
<td><xsl:value-of select=".//release-date" /></td>
<td><xsl:value-of select=".//author" /></td>
<td><xsl:value-of select="@price" /></td>
</tr>
</xsl:for-each>
2.排序 <xsl:sort...>
3.条件处理 <xsl:if...>或<xsl:choose...>或<xsl:when...>
4.名称模板
<xsl:template name...<xsl:template name...>,<xsl:param...>
<xsl:with-param...>,<xsl:call-template...>
5.编号方式 <xsl:number value format...>
关于语法的具体学习,看http://www.w3schools.com/xsl/default.asp
6、XSL样式单
一个XSL文件也是XML文件,所以第一行也要声明XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
第二行XSL声明,下述声明方式是完全一致的:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
和
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
当用上述命名空间时,必须有version="1.0"的说明。
看列例子:XML文件,XSL文件,XML+XSL.
7、<xsl:template>元素
XSL样式单是由模板组成,每个模板就是一组规则。
模板的match属性,用以将模板和XML中的元素关联起来。如match="/"则将此模板与XML的根关联起来了。
8、<xsl:value-of>元素
该元素用于取得选定XML节点的值。
对节点的选取,由其select属性完成,select的值是一个XPath表达式。XPath表达式非常象*nix系统的多级目录的写法。如例中的“breakfast_menu/food”等。
9、<xsl:for-each>元素
完成在XSL中的循环动作。其属性select同6中所述。
此元素可以完成简单的过滤,例如:
<xsl:for-each select="catalog/cd[artist='Bob Dylan']">
可用于寻找Bob Dylan的CD作品。XSL定义了四种比较运算符:=、!=、<、>,两个比较之间可以用and 或or 连接。
10、<xsl:sort>元素
用于对输出进行排序,只需要将其放入<xsl:for-each>以内,并用select指明比较的元素即可。
11、<xsl:if>元素
当指定条件满足时,<xsl:if>包含的模板将派上用场。条件的定义,由其test属性指明,其操作符同7。
一般说来,<xsl:if>常出现在<xsl:for-each>内部。
12、<xsl:choose>、<xsl:when>、<xsl:otherwise>元素
三者联合,实现多条件选择,类似C语言里的case语句。如例:
<xsl:choose>
<xsl:when test="price > 10">
some code
</xsl:when>
<xsl:otherwise>
some code .
</xsl:otherwise>
</xsl:choose>
11、<xsl:apply-templates>元素
对当前元素和其子元素使用某一模板规则,象C里的递规函数,暗含着循环的功能。其用select属性指明元素。相对应的模板,则需要用match来判断传来的是什么元素,从这一点看模板象是C++里的重载函数。
1、<xsl:import>、<xsl:include>、<xsl:apply-imports>元素
<xsl:import>与<xsl:include>相比,两者都须是<xsl:stylesheet>的子结点,但前者定义的模板规则优先级比较低,且必须为第一个子结点。两者的功能是相同的,都是将另一个定义好的XSL文件装入到当前XSL文件中来。
装来的模板规则,由<xsl:apply-imports>指定何时何地使用。
它们的语法分别是:
<xsl:import href="URI"/>
<xsl:apply-templates />
2、<xsl:attribute>、<xsl:attribute-set>元素
前者用以给元素增加属性,已有同名属性则被它替换。后者是<xsl:stylesheet>的子结点,用来定义一组属性,将其用于整个文档。语法如下:
<xsl:attribute name="attributename" namespace="uri"><!-- Content:template --></xsl:attribute>
<xsl:attribute-set name="name" use-attribute-sets="name-list"><!-- Content:xsl:attribute* --></xsl:attribute-set>
namespace可选,use-attribute-sets可选,用以使用其它预定义的attribute-set.
3、<xsl:param>、<xsl:call-template>、<xsl:with-param>元素
<xsl:param>用来定义全局参数(是<xsl:styelsheet>的子点时)或局域参数(在一个模板内时),<xsl:call-template>用来调用指定的模板,<xsl:with-param>则用来调用模板或使用模板时传递参数。需要说明的是,with-param的name属性的值必须与预定义的值一致。语法如下:
<xsl:param name="name" select="expression"><!-- Content:template --></xsl:param>
<xsl:call-template name="templatename"><!-- Content:xsl:with-param* --></xsl:call-template>
<xsl:with-param name="name" select="expression"><!-- Content:template --></xsl:with-param>
其中的select都是可选的,前者的select用来指定默认值,后者可以来传值(也可用标签的内容传值)。
4、<xsl:variable>元素
定义全局或局部变量,其一旦赋值,不能改动。语法:
<xsl:variable name="name" select="expression"><!-- Content:template --></xsl:variable>
5、<xsl:copy>、<xsl:copy-of>元素
两者都复制当前节点及其命名空间,但后者还复制子结点和当前结点属性。语法如下:
<xsl:copy-of select="expression"/>
<xsl:copy use-attribute-sets="name-list"><!-- Content:template --></xsl:copy>
其中use-attribute-sets可选。
6、<xsl:comment>元素
在结果树中生成一个注释结点。语法如下:
<xsl:comment><!-- Content:template --></xsl:comment>
7、<xsl:decimal-format>元素
定义那些在调用函数format-number()进行由数字向字符器转换的过程中用到的一些特殊字符或符号。语法如下:
<xsl:decimal-format name="name" decimal-separator="char" grouping-separator="char" infinity="string"
minus-sign="char" NaN="string" percent="char" per-mille="char" zero-digit="char" digit="char" pattern-separator="char"/>
所有项是可选的。
8、<xsl:element>元素
在结果树上生成一个元素,语法如下:
<xsl:element name="name" namespace="URI" use-attribute-sets="namelist"><!-- Content:template --></xsl:element>
其中后两个属性是可选的,前俩者的值可在实时运行时算出。
9、<xsl:fallback>元素
当xsl的元素不能被处理器识别时,调用fallback提供的备用程序。
<xsl:fallback><!-- Content: template --></xsl:fallback>
10、<xsl:key>元素
这是一个顶层元素,定义一个KEY供Key函数使用。
<xsl:key name="name" match="pattern" use="expression"/>
11、<xsl:message>元素
用来输出信息,如错误信息。所有的其它元素都可出现在其内容中。
<xsl:message terminate="yes|no"> <!-- Content:template --></xsl:message>
12、<xsl:namespace-alias>元素
用来在输出时将某命名空间替换为另一个。
<xsl:namespace-alias stylesheet-prefix="prefix|#default" result-prefix="prefix|"#default"/>
13、<xsl:number>元素
用以标明当前结点在源树中的顺序,也可以用格式化一个数。
<xsl:number count="expression" level="single|multiple|any" from="expression" value="expression" format="formatstring"
lang="languagecode" letter-value="alphabetic|traditional" grouping-separator="character" grouping-size="number"/>
14、<xsl:output>元素
用以定义output的格式,
<xsl:output method="xml|html|text|name" version="string" encoding="string" omit-xml-declaration="yes|no"
standalone="yes|no" doctype-public="string" doctype-system="string" cdata-section-elements="namelist"
indent="yes|no" media-type="string"/>
15、<xsl:preserve-space>、<xsl:strip-space>元素
两者用来指明元素内容的空格保留还去掉。由于默认是保留的,所以只有在用了去掉时才需指明保留者。
<xsl:preserve-space elements="list-of-element-names"/>
<xsl:strip-space elements="list-of-element-names"/>
list-of-element-names的值中可用*通配符。
16、<xsl:processing-instruction>元素
用来向输出写处理指令,如指定css文件等。
<xsl:processing-instruction name="process-name"><!-- Content:template --></xsl:processing-instruction>
17、<xsl:text>元素
用来输出字串常量。
<xsl:text disable-output-escaping="yes|no"> <!-- Content:#PCDATA --></xsl:text>
从XML文档开始
首先从打算转换成HTML的XML文档开始:
<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
如果使用的是Internet Explorer 5.0或更高版本,就可以查看这个XML文件的 显示结果。
创建一个XSL样式表文档
现在用转换模板来创建一个XSL样式表:
如果使用的是Internet Explorer 5.0或更高版本,就可以查看这个XSL文件的 显示结果。
将样式表连接到XML文档
现在向XML文档中增加一个XSL样式表引用:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="cd_catalog.xsl"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
如果有一个与XSL兼容的浏览器,例如Internet Explorer 5.0或更高版本,那么就能很好地将XML转换成HTML。点击这里 查看结果。
XSL如何使用模板来定义从XML到另一种输出格式的转换
XSL模板
XSL用模板来描述如何输出 XML。
CSS的使用规则
如果已经学习过CSS的知识,我们就会知道CSS是用一个或多个规则来定义HTML元素的输出,用一个选择器将规则与一个HTML元素联系起来。比如以下这个CSS规则中的p选择器说明应该用一种叫做arial的字体来显示一个<p>元素:
p { font-family: arial }
XSL使用模板
XSL使用一个或多个模板来定义如何输出XML元素,用一个匹配属性来将模板与一个XML元素联系起来,还可以用匹配属性来为XML文档的一个完整分支来定义模板。
请看以下的XSL样式表,它包含一个模板以输出前一节中的XML CD目录:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td>.</td>
<td>.</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
由于样式表本身就是一个XML文档,因此文档以一个xml声明开始:<?xml
客户端XSL:如何用XML解析器在客户机上将XML文档转换成HTML文档。
一个JavaScript的解决方法
在前文中,我们解释了如何用XSL将一个文档从XML转换成HTML。窍门就是向XML文件中增加一个XSL样式表,然后让浏览器来进行转换。即使这种方法能奏效,在XML文件中包含一个样式表引用也并非令人满意的方法,并且在不支持XSL的浏览器上这种方法还不能奏效。
一个更通用的方法应该是用一个JavaScript来进行从XML到HTML的转换。使用一个JavaScript,就更有以下可能性:
- 允许JavaScript进行浏览器细节测试;
- 根据浏览器和用户需求使用不同的样式表。
- 这就是XSL的美妙之处。XSL设计目的之一就是使数据从一个格式转换成另一个格式成为可能,从而支持不同的浏览器和不同的用户需求。
- 客户端XSL转换将成为未来浏览器工作任务的一个主要部分,我们还将看到专业化浏览器市场的成长,比如Braille、发声网络、网络打印机、手持PC、移动电话等。
XML文件和XSL文件
现在重新来看看前面章节中的XML文档:
<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
.
.
.
还有附带的XSL样式表:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="CATALOG/CD">
<tr>
<td><xsl:value-of select="TITLE"/></td>
<td><xsl:value-of select="ARTIST"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
要确保XML文件没有对XSL文件的引用,XSL文件也没有对XML文件的引用。注意:上面的句子说明一个XML文件可以用许多不同的XSL文件进行转换。
在浏览器中将XML转换到HTML
以下是在客户机上将XML文件转换成HTML所需要的源代码,很简单:
<html>
<body>
<script language="javascript">
// Load XML
var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load("cd_catalog.xml")
// Load the XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load("cd_catalog.xsl")
// Transform
document.write(xml.transformNode(xsl))
</script>
</body>
</html>
如果使用的是Internet Explorer 5.0 或更高版本,请点击这里 查看结果。
代码的第一块创建了Microsoft XML 解析器(XMLDOM)的一个例示,并将XML文档加载到内存中。代码的第二块创建解析器的另一个例示,并将XSL文档加载到内存中。代码的最后一行用XSL文档转换XML文档,将结果写入HTML 文档中。
服务器端XSL:如何用XML解析器在服务器上将XML文档转换成HTML文档。
服务器端XSL
由于不是所有的浏览器都支持XML和XSL,因此就有了一个在服务器上将XML转换成HTML的方法。
一个跨浏览器的解决方法
在前面的章节中,我们解释了如何用XSL在浏览器中将XML文档转换成HTML,窍门就是让JavaScript使用一个XML解析器来进行转换。但是当浏览器不支持XML解析器时,这种方法是不奏效的。要使XML数据对所有浏览器都可用,我们就必须在服务器上转换XML文档,并将它作为纯HTML发送到浏览器。
这是XSL的另一个美妙之处。XSL的设计目的之一是使得在服务器上将数据从一种格式转换成另一种格式成为可能,并将可读数据返回到所有未来的浏览器中。
在服务器上进行XSL转换正在成为未来Internet信息服务器工作任务的一个主要部分,同时我们将看到专用浏览器市场的发展,如:Braille、有声网络、网络打印机、手持PC、移动电话等。
XML文件和XSL文件
现在来重新看看前面章节中的XML文档:
<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
.
.
.
如果使用的是Internet Explorer 5.0或更高版本,可以点击这里查看 XML文件。
再看看伴随的XSL样式表:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="CATALOG/CD">
<tr>
<td><xsl:value-of select="TITLE"/></td>
<td><xsl:value-of select="ARTIST"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
如果使用的是Internet Explorer 5.0或更高版本,可以点击这里查看 XSL文件。
以上XSL文档的语法在前面章节中已经解释过了,因此这里不再做解释。但是要确保XML文件没有对XSL文件的引用,XSL文件也没有对XML文件的引用。同时请注意:上面的句子表明一个服务器上的XML文件可以用许多不同的XSL文件进行转换。
在服务器端将XML转换成HTML
以下是在服务器上转换XML文件所需要的简单源代码:
<%
'Load the XML
set xml = Server.CreateObject("Microsoft.XMLDOM")
xml.async = false
xml.load(Server.MapPath("cd_catalog.xml"))
'Load the XSL
set xsl = Server.CreateObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(Server.MapPath("cd_catalog.xsl"))
'Transform the file
Response.Write(xml.transformNode(xsl))
%>
代码的第一块创建Microsoft XML解析器(XMLDOM)的一个例示,并将XML文件装载到内存中。代码的第二块创建解析器的另一个例示,并将XSL文档装载到内存。代码的最后一行用XSL文档转换XML文档,并将结果返回浏览器。
XSL索引:将XML文档转换成HTML之前,如何用XML解析器来对XML文档进行索引。
XSL索引
XSL可以用来对一个XML文档进行索引。
将索引信息放在哪里
现在重新看看在以前许多章节中都曾看到过的 XML文档:
<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
.
.
.
要想将这个XML文件作为一个普通的HTML文件输出,并且同时对它进行索引,只需要在XSL文件中增加一个order-by 属性,如下:
<xsl:for-each select="CATALOG/CD" order-by="+ ARTIST">
order-by属性使用加号(+)或减号(-)来定义是使用升序还是降序,再用一个元素名称来定义排序的元素。
现在来看看经过轻微调整的XSL样式表(或在IE5中打开它):
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="CATALOG/CD"
order-by="+ ARTIST">
<tr>
<td><xsl:value-of select="TITLE"/></td>
<td><xsl:value-of select="ARTIST"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
在浏览器中转换
以下是在浏览器中将XML文件转换成HTML所需要的简单代码:
<html>
<body>
<script language="javascript">
// Load XML
var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load("cd_catalog.xml")
// Load the XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load("cd_catalog_sort.xsl")
// Transform
document.write(xml.transformNode(xsl))
</script>
</body>
</html>
如果使用的是Internet Explorer 5.0 或更高版本,请点击这里 查看结果。
XSL过滤器:将XML文档转换成HTML之前,如何用XML解析器过滤XML文档。
XSL过滤器查询
XSL可以用来过滤一个 XML 文件。
在哪里放置过滤器信息
现在重新看看你以前已经看过多次的XML文档:
<?xml version="1.0"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
.
要过滤XML文件,只需要为XSL文件中的for-each元素的选择属性增加一个过滤器,如下:
<xsl:for-each select="CATALOG/CD[ARTIST='Bob Dylan']">
合法的过滤器操作符是:
现在看看经过轻微调整的XSL样式表:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:template match="/">
<html>
<body>
<table border="2" bgcolor="yellow">
<tr>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="CATALOG/CD[ARTIST='Bob Dylan']">
<tr>
<td><xsl:value-of select="TITLE"/></td>
<td><xsl:value-of select="ARTIST"/></td>
</tr>
</xsl:for-each>
</ta