1. XSLT是XSLTransformations的缩写,它是XSL的一个组成部分。
XSL(EXtensible StyleSheet)由三部分组成:
– XSLT。XSLT的作用是将一个XML文档转换为另一种类别的XML文档(也包括HTML文档)。
– XPath。XPath的作用是指定访问XML数据的寻址路径表达式。
– XSL-FO(XSL Formatting Objects)。XSL-FO的作用是对XML文档中的数据排版
2. XSLT工作原理:将如下XML文档转换为HTML文档
<?xml version="1.0" encoding="GBK" ?> <?xml-stylesheet type="text/xsl" href="books.xsl" ?> <books> <book category="TP18"> <title lang=”cn”>人工智能及其应用</title> <authors> <author>蔡自兴</author> <author>徐光祐</author> </authors> <ISBN>7-302-02127-9</ISBN> <date>1996年5月</date> <publisher>清华大学出版社</publisher> <price>32.50</price> </book> </books>
相应的XSLT文档:
<?xml version="1.0" encoding="GBK" ?> <xsl:stylesheet version="1.0 " xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/books/book"> <table border="1"> <tr> <td bgcolor="#9acd32">标题</td> <td><xsl:value-of select="title" /></td> </tr> <tr> <td bgcolor="#9acd32">作者</td> <td><xsl:for-each select="authors/author"> <xsl:value-of select="." /> <![CDATA[ ]]> </xsl:for-each> </td> </tr> <tr> <td bgcolor="#9acd32">出版社</td> <td><xsl:value-of select="publisher" /></td> </tr> </table> <br/> </xsl:template> </xsl:stylesheet>
转换后产生的HTML文档:
<table border="1"> <tr> <td bgcolor="#9acd32">标题</td> <td>人工智能及其应用</td> </tr> <tr><td bgcolor="#9acd32">作者</td> <td>蔡自兴 徐光祐</td> </tr> <tr> <td bgcolor="#9acd32">出版社</td> <td>清华大学出版社</td> </tr> </table>3. XSLT工作原理
4.将XML转换为HTML
• 要将XML文档转换为HTML,除了要进行转换的XML文件本身之外,还需要一个指定转换规则的XSLT文件,此外,还必须在XML文件中指出对应的XSLT文件的URL。
• 在XML文件中,必须在开头放置一条处理指令,其格式为:
<?xml-stylesheettype=“text/xsl” href=”your-xsl-file-URL”?>
• 在XSLT文件中,其根元素必须是stylesheet,并且必须声明XSLT的命名空间,为这个空间指定前缀,例如:
<xsl:stylesheet version=”1.0”xmlns:xsl=http://www.w3.org/1999/XSL/Transform >
• 可在IE浏览器上直接打开XML文件,IE包含的XSLT处理器将按照XSLT文件中的指令对XML文件进行转换,并将转换的结果显示在窗口上。
5.XML文档结构树 ML文档的数据结构是树形结构,XSLT事实上可以认为是将一颗XML树转换为另一颗不同结构的XML树。• 无论一棵XML树结构如何复杂,它都是由如下7种结点构成的:
1.文档根结点,这是一个代表整个XML文档的结点。/
2. 元素结点,XML文档中每一个元素对应一个元素结点。
3. 文本结点,包含在一个元素中的文字对应一个文本结点,如果其中出现CDATA片断,则CDATA片断中的文字也包含在这个文本结点中。
4. 属性结点,一个元素如果包含属性,则每一个属性对应一个属性结点。
5. 处理指令结点,XML文档中每一条处理指令对应一个处理指令结点。
6. 注释结点,XML文档中每一个注释标记对应一个注释结点。
7. 命名空间结点,对应命名空间的结点,注意并非XML文档中出现几个命名空间,就对应几个命名空间结点,而是有数量多得多的命名空间结点。命名空间结点依附于元素结点,一个元素处于哪些命名空间的作用域内,这个元素结点就拥有哪些命名空间结点,一个命名空间对应一个结点。
XSLT不处理命名空间结点,因此XSLT所处理的结点只有6种,其中最重要的是文档根结点、元素结点、文本结点和属性结点。6.模板和指令
- 模板:xsl:template
- 取值:xsl:value-of
- 循环:xsl:for-each
- 过滤和排序
- 选择:xsl:if
- 多分支选择:xsl:choose
- 模板的应用:xsl:apply-templates
- 默认模板
- 对源文档结点的处理次序
(1)模板:xsl:template
•XSLT的转换规则由若干个模板构成,每个模板利用XPath表达式指定应用的结点,当XML文档中的结点与指定的结点匹配时,就应用这个模板。
•模板的常见形式为 :
<xsl:templatematch=“pattern” >
… … <!-- 模板的内容 -->
</xsl/template>
其中pattern为XPath表达式。
•模板存放在XSLT文档中,XSLT处理器将从文档根结点开始搜索源文档树中的结点,一旦发现某个结点有匹配的模板,则该结点及其子树(以该结点为树根的子树)就由该模板处理。
•模板的内容指出如何处理所匹配子树中的结点,其中包括直接输出的标记(非XSLT命名空间的标记)和XSLT指令(XSLT命名空间的标记)。
模板的XPath表达式举例:
•/与根结点匹配。
*与任何元素和属性结点匹配。
chapter/para与chapter结点的子结点para匹配。
@id,与属性id•chapter[@id=”1”]与属性的值为1的结点.当前结点。
例如:
<xsl:template match=”/books/book” >
<xsl:template match=”/books/book[@category=’TP312’]” >
方括号中的布尔表达式称为“谓词”,它表示一个过滤条件,只有满足过滤条件的结点才被过滤出来作为匹配结点。
(2)取值:xsl:value-of
•xsl:value-of可用来取出结点的字符串值。
•常用形式:
<xsl:value-of select=”pattern”/>
•例如:
<xsl:value-of select=”title” >
<xsl:value-of select=”title/@lang” >
(3)循环:xsl:for-each
•常用形式 :
<xsl:for-eachselect=”pattern” >
… <!-- 对pattern所匹配结点的处理-->
</xsl:for-each>
•通常pattern匹配多个结点,xsl:for-each将对所匹配的每个结点执行一遍。
•例如:
<xsl:for-eachselect=”/books/book” >
… <!-- 处理每个book结点 -->
</xsl:for-each>
For-each示例:
一本书可以有多个作者,我们可以循环地取出每个作者的姓名:
<xsl:for-each select=”authors/author”>
<!-- 对authors的每个author结点循环处理 -->
<xsl:value-ofselect=”.” />
<!-- 当前结点就是author,得到作者姓名 -->
<![CDATA[ ]]>
<!-- 此处放一个空格,隔开作者姓名 -->
</xsl:for-each>
(4)过滤
•在用于select的XPath表达式中使用谓词可以实现过滤。
•谓词由一对方括号括起来,其中是一个表示条件的等式或不等式,只有满足条件的结点才被选中。
•例如,只显示出某个出版社出版的书籍:
<xsl:template match=“/books/book[publisher=‘清华大学出版社’]” >
•用于过滤表达式的一些运算符:
=,等于 !=,不等于 < 小于 > 大于 注意大于、小于不能用“>”和“<”
排序:
•排序要使用<xsl:sort>元素 。
•<xsl:sort>可作为<xsl:for-each>或<xsl:apply-templates>的子元素使用,从而使循环处理的结果按指定的次序排序。
•默认的情况下,排序是按升序次序的,如果要改变,可使用<xsl:sort>的属性order,其属性值为ascending或descending。例如,使标题按降序排列:
<xsl:sortselect="title“order="descending" />
排序示例1:按书本标题排序:<xsl:template match="/"> <html> <body> <table> <xsl:for-each select="/books/book"> <xsl:sort select="title" /> <tr> <td><xsl:value-of select="title" /></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template>
排序示例2:
•也可以按属性值排序 ,例如: <xsl:for-each select="/books/book"> <xsl:sort select="@category" /> <tr><td> <xsl:value-of select="title" /> :category is <xsl:value-of select="@category" /> </td></tr> </xsl:for-each> •如果按价格排序,由于价格是数字,最好指出所排序的数据是数字 : <xsl:sort select="price" data-type="number" /> data-type的属性值可取“text”或“number”。
5.选择:xsl:if
• xsl:if可用来设定一个条件,只对满足条件的数据进行处理。
• 一般应用形式为:
<xsl:iftest=boolean-expression >
<!–
此处对满足条件的数据进行转换处理
-->
</xsl:if>
• 其中boolean-expression是一个布尔表达式,用来表示条件。
选择举例:ibri;ms"Cni`�X�nt:minor-latin'>注释结点,XML文档中每一个注释标记对应一个注释结点。7. 命名空间结点,对应命名空间的结点,注意并非XML文档中出现几个命名空间,就对应几个命名空间结点,而是有数量多得多的命名空间结点。命名空间结点依附于元素结点,一个元素处于哪些命名空间的作用域内,这个元素结点就拥有哪些命名空间结点,一个命名空间对应一个结点。
XSLT不处理命名空间结点,因此XSLT所处理的结点只有6种,其中最重要的是文档根结点、元素结点、文本结点和属性结点。•选择价格大于30的书籍,并列出标题和价格 : <xsl:for-each select="/books/book"> <xsl:if test="price > 30"> <tr> <td><xsl:value-of select="title" />: price=<xsl:value-of select="price"/> </td> </tr> </xsl:if> </xsl:for-each>
6.多分支选择:
•<xsl:choose>的作用类似于C语言的switch或PASCAL的case,其格式为: <xsl:choose> <xsl:when test=boolen-expression-1> … <!-- 处理满足boolen-expression-1的数据 --> </xsl:when> <xsl:when test=boolen-expression-2> … <!-- 处理满足boolen-expression-2的数据 --> </xsl:when> … <!-- 其它xsl:when --> <xsl:otherwise> … <!-- 处理其它情况 --> </xsl:otherwise> </xsl:choose> 多分支选择示例: <xsl:choose> <xsl:when test="publisher='清华大学出版社'"> <td bgcolor="yellow"> <xsl:value-of select="title" />, <xsl:value-of select="publisher" /></td> </xsl:when> <xsl:when test="publisher='电子工业出版社'"> <td bgcolor="lime"> <xsl:value-of select="title" />, <xsl:value-of select="publisher" /></td> </xsl:when> <xsl:otherwise> <td bgcolor="white"> <xsl:value-of select="title" />, <xsl:value-of select="publisher" /></td> </xsl:otherwise> </xsl:choose>
7.模板的应用:xsl:apply-templates
• 复杂的转换需要使用多个模板,每一个模板负责处理一部分结构。
• 模板的作用类似于程序设计语言中的子程序,而应用模板类似于调用子程序。
• 定义模板的语法前已述及。
• 应用模板的语法:
<xsl:apply-templates
select=”node-set-expression”>
<!-- <xsl:sort> 或<xsl:with-param> -->
</xsl:apply-templates>
• 其中的node-set-expression是一个XPath表达式,指出需要应用模板的结点集。如果某个模板的match属性值pattern与node-set-expression匹配,则应用这个模板处理这个结点集。
•
应用模板:
• 如果应用模板时不使用xsl:sort或 xsl:with-param,则可以简化为:
<xsl:apply-templates
select=”node-set-expr”/>
• 如果对当前结点的所有子结点应用模板 :
<xsl:apply-templates/>
注意这条指令不是对当前结点应用模板,而是对当前结点的所有子结点,而在所有结点中,只有文档根结点和元素结点才有子结点,并且属性结点并非它们的子结点。
模板应用示例(1):
匹配<book>的模板:<xsl:template match="book"> <p>标题: <xsl:value-of select="title" />,类别:<xsl:value-of select="@category" /></p> <p>作者:<xsl:apply-templates select="authors"/>, ISBN:<xsl:value-of select="ISBN" /></p> <p>出版社:<xsl:value-of select="publisher" />, 出版日期:<xsl:value-of select="date" /></p> <hr size="3"/> </xsl:template> 模板应用示例(2): 匹配<authors>的模板: <xsl:template match="authors"> <xsl:for-each select="author"> <xsl:value-of select="." > <![CDATA[ ]]> </xsl:for-each> </xsl:template>
CDATA标记包含的文字将被作为文本复制到目的文档中,此处CDATA所包含的文字是一个空格。
模板应用示例(3)
调用上述两个模板:<xsl:template match="/"> <html> <body> <xsl:apply-templates /> </body> </html> </xsl:template>
8.默认模板
• 用户编写的全体模板并不需要覆盖源文档树中的每一个结点。
• XSLT处理器有一些内置的默认模板,对于用户编写的模板没有包含的结点,XSLT处理器将应用默认的模板来处理这些结点。
• XSLT文档中用户编写的模板优先于默认模板。
默认模板有3个 :1. <xsl:template match="*|/" > <xsl:apply-templates /> </xsl:template> 2. <xsl:template match="text()|@*" > <xsl:value-of select="." /> </xsl:template> <xsl:template match="processing-instruction()|comment()" />
对于如下XML文档和XSLT文档,转换的结果是什么?
9、对源文档结点的处理次序
• XSLT处理器对源文档树中的结点进行处理时,结点的处理次序由XSLT文档中用户编写的模板和处理器默认的模板共同决定。
• 首先,XSLT处理器对文档根结点调用匹配的模板,如果没有匹配的用户模板,则调用默认模板,其结果是对文档根结点的每个子结点调用模板,至于这些子结点的先后次序,则按照它们在文档中出现的先后次序。
• 对于每个子结点,重复以上过程。一旦一个结点与某个用户模板匹配,则该结点及其为根的子树就交由用户模板处理,用户模板中的指令决定这棵子树中各个结点的处理次序。如果没有任何用户模板与之匹配,则调用匹配的默认模板。
• 属性结点不是任何结点的子结点,因此尽管有一个匹配属性结点的默认模板,但反复执行<xsl:apply-templates />并不能调用这个模板。要处理属性结点,必须在用户模板中有相应的指令,例如,
<xsl:apply-templates select="@*" />
<xsl:value-of selelct="@*" />