Web Services 应用开发学习笔记(四):XML显示—XSL
1.引言
下面是一个xml的文件,如果用浏览器直接打开,会是什么效果呢?
product.xml
<?xml version="1.0" encoding="gb2312"?>
<PRODUCTS>
<PRODUCT PRODID="p001" CATEGORY="Toy">
<PRODUCTNAME>模型飞机</PRODUCTNAME>
<DESCRIPTION>适合于5岁以上儿童</DESCRIPTION>
<PRICE>239</PRICE>
<QUANTITY>20</QUANTITY>
</PRODUCT>
<PRODUCT PRODID="p002" CATEGORY="Toy">
<PRODUCTNAME>电动汽车</PRODUCTNAME>
<DESCRIPTION>适合4岁以上儿童</DESCRIPTION>
<PRICE>860</PRICE>
<QUANTITY>12</QUANTITY>
</PRODUCT>
</PRODUCTS>
很显然,浏览器仅仅是作为一个xml文件的解析器,无法理解这些标记的含义,所以它就将文件原封不动的显示出来。嘿嘿!想要控制xml像web页面那样显示,就需要用到W3C推荐的样式表标准:CSS级联样式表和XSL可扩展样式表。
2.CSS级联样式表
CSS是一种文本文档,用于控制XML文档和HTML文档中的标签如何被格式化。简单点来说, 怎样去显示文档中的内容。
不过CSS与XML结合时存在局限性:
(1)CSS可以格式化XML文档,能够很好的控制输出的样式,比如色彩、字体、大小等,但只能静态控制文档的样式或外观
(2)CSS不能重新排序文档中的元素
(3)CSS不能动态判断和控制元素的显示
(4)CSS无法动态统计元素中的数据
至于CSS的语法规则这里不多说,可以去参考其他资料
那应该如何让XML与CSS关联起来呢?
在XML中通过xml-stylesheet指令引入CSS样式表,其语法格式如下:
<?xml-stylesheet type="text/css" href="location" ?>
(2)<?xml-stylesheet?>处理指令中的href属性值是一个URL,通常是相对值,指明在何处可找到样式表。如果样式表没有找到,Web浏览器很可能使用其缺省的样式表,此时浏览器可能会报告一条错误信息
现在我们引入product.css:
product.xml:
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type="text/css" href="product.css"?>
<PRODUCTS>
<PRODUCT PRODID="p001" CATEGORY="Toy">
<PRODUCTNAME>模型飞机</PRODUCTNAME>
<DESCRIPTION>适合于5岁以上儿童</DESCRIPTION>
<PRICE>239</PRICE>
<QUANTITY>20</QUANTITY>
</PRODUCT>
<PRODUCT PRODID="p002" CATEGORY="Toy">
<PRODUCTNAME>电动汽车</PRODUCTNAME>
<DESCRIPTION>适合4岁以上儿童</DESCRIPTION>
<PRICE>860</PRICE>
<QUANTITY>12</QUANTITY>
</PRODUCT>
</PRODUCTS>
product.css:
PRODUCTNAME
{font-family:Arial;
font-size:20pt;
font-weight:bold;
color:red;
display:block;
padding-top:6pt;
padding-bottom:6pt
}
PRICE,DESCRIPTION,QUANTITY
{font-family:Arial;
font-size:12pt;
color:teal;
display:block;
padding-top:3pt;
padding-bottom:3pt
}
浏览器效果:
3.XSL基础
如果说HTML与CSS是最佳搭档的话,那么XSL就是XML的就是天作之和了。先来看基本的定义
XSL(eXtensible Stylesheet Language)是一种基于XML的语言,是一种显示XML文件的规范,遵循XML的规范制定。
XSL实际上包含三种语言:
(1)XSLT是一种转换XML的语言,着重于XML文档转换
(2)XPath是一种用来访问XML文档不同部分或模式的语言,着重于从XML层次结构上访问结点
(3)XSLFO(XSL格式化对象)是一种定义XML显示方式的语言,着重于格式对象,作用就类似CSS在HTML中的作用
4.XSL文档结构
XSL文档本身是格式良好的XML文档,在XSL文件的开头要有和XML文件相同的声明,XSL文档的标准格式如下
<xsl:stylesheet version="1.0“
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
模板规则
输出模板
</xsl:stylesheet>
语法解析:
例子:
student.xml:
<?xml version="1.0" encoding="gb2312"?>
<?xml-stylesheet type="text/xsl" href="student.xsl"?>
<class>
<student ID="101">
<name>李华</name>
<sex>男</sex>
<birthday>1988.12.12</birthday>
<score>92</score>
<skill>Java</skill>
</student>
<student ID="102">
<name>王燕</name>
<sex>女</sex>
<birthday>1989.9.10</birthday>
<score>89</score>
<skill>Visual Basic</skill>
</student>
<student ID="103">
<name>张磊</name>
<sex>男</sex>
<birthday>1987.9.9</birthday>
<score>98</score>
<skill>UML</skill>
</student>
<student ID="104">
<name>杨菲</name>
<sex>女</sex>
<birthday>1989.6.16</birthday>
<score>85</score>
<skill>SQL Server</skill>
</student>
</class>
student.xsl:
<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>学生成绩单</title>
</head>
<body>
<h2 align="center">学生成绩单</h2>
<table border="2" cellpadding="0" align="center">
<tr bgcolor="#9acd32">
<th>姓名</th>
<th>性别</th>
<th>生日</th>
<th>成绩</th>
</tr>
<xsl:for-each select="/class/student">
<tr>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:value-of select="sex"/>
</td>
<td>
<xsl:value-of select="birthday"/>
</td>
<td>
<xsl:value-of select="score"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
浏览器效果:
5.XSL元素
示例代码
模板匹配所有的name元素:
<xsl:template match="name">
</xsl:template>
<xsl:template match="student//name">
</xsl:template>
(2)<xsl:value-of>元素
<xsl:value-of select ="匹配模式"/>
(3)<xsl:for-each>元素
若想循环选择多条数据,可使用<xsl:for-each>元素。其语法格式如下:
<xsl:for-each select="匹配模式">
<!--输出内容-->
</xsl:for-each>
(4)<xsl:sort>元素
<xsl:sort select="匹配模式" order="ascending|descending"
case-order="upper-first|lower-first" data-type="text|number|qname"/>
(5)<xsl:if>元素
<xsl:if>类似普通程序语言的if条件语句,允许设定节点满足某个条件时,被模板处理。其语法格式如下:
<xsl:if test="匹配模式">
<!--输出内容-->
</xsl:if>
(6)<xsl:choose>元素
<xsl:choose>
<xsl: when test="匹配模式">
<!--输出内容-->
</xsl:when>
<xsl:when test="匹配模式">
<!--输出内容-->
</xsl:when>
... ...
<xsl:otherwise>
<!--输出内容-->
</xsl:otherwise>
</xsl:choose>
(7)<xsl:apply-templates>元素
<xsl:apply-templates select ="匹配模式">
</xsl:apply-templates>
6.XSLT
XSLT(eXtensible Stylesheet Language Transformation)是一种用来转换XML文档结构的语言。
XSL的处理过程:
首先是根据XML文档构造源树,然后根据XSL规则将源树转换为结果树,生成结果树后,对其进行解释,格式化为一种适合显示、打印或是播放的格式。
CSS |
XSLT |
使用简单 |
使用复杂 |
不能排序、添加或删除元素 |
可排序、添加或删除元素 |
不能访问文档除元素外的其它信息 |
能访问其它信息 |
使用内存比较少 |
使用较多内存和处理器能力 |
与XML语法不同 |
语法与XML相同 |
7.XPath基础
XPath就是一种专门用来在XML文档中定位和查找信息的语言,通过XPath可对XML文档中的元素和属性进行遍历,是高级XML应用的基础 。
XPath主要有四种数据类型:
(1)节点集
(2)布尔类型
(3)字符串类型
(4)数值类型
在XPath中,可以将节点划分为七种节点类型:
(1)根节点(Root Node)
(2)元素节点(Element Nodes)
(3)文本节点(Text Nodes)
(4)属性节点(Attribute Nodes)
(5)命名空间节点(Namespace Nodes)
(6)处理指令节点(Processing Instruction Nodes)
8.XPath表达式
XPath将XML文档看作由节点构成的层次树,通过编写XPath表达式来定位树中特定的节点
XPath路径表达式:
表达式 |
描述 |
nodename |
选取此节点的所有子节点 |
/ |
从根节点选取,绝对路径,表示当前文档的根节点 |
// |
从任意节点选取,相对路径,表示当前文档所有的节点 |
. |
选取当前节点 |
.. |
选取当前节点的父节点 |
@ |
选取属性 |
例子:
<?xml version="1.0" encoding="GB2312"?>
<bookstore>
<book>
<title lang="en">RESTful Web Services</title>
<price>29.00</price>
</book>
<book>
<title lang="zh">C#编程基础</title>
<price>46.00</price>
</book>
</bookstore>
解析:
bookstore |
选取 bookstore 元素的所有子节点 |
/bookstore |
选取根节点bookstore元素 |
/bookstore/book/price |
选取bookstore元素下所有book元素的所有price元素 |
/bookstore/book/* |
选取/bookstore/book的所有子元素 |
bookstore/book |
选取bookstore元素下所有的book子元素 |
//bookstore |
选取文档中所有的bookstore元素,无论它在什么层次 |
bookstore//book |
选取在bookstore元素下所有的book元素,无论它们位于bookstore之下的什么位置 |
/bookstore/*/price |
选取bookstore的子元素中,包含有price作为子元素的元素 |
//* |
选取文件中的所有元素 |
//@lang |
选取所有名为 lang 的属性 |
谓语表达式:
路径表达式 |
描述 |
/bookstore/book[last()] |
选取属于bookstore子元素的最后一个book元素 |
/bookstore/book[last()-1] |
选取属于bookstore子元素的倒数第二个book元素 |
/bookstore/book[position()<3] |
选取前两个属于bookstore元素的子元素的book元素 |
//title[@lang] |
选取所有拥有名为lang的属性的title元素 |
//title[@lang="en"] |
选取所有title元素,且这些元素拥有值为 eng 的 lang 属性 |
/bookstore/book[price>15.00] |
选取所有bookstore元素的book元素,且其中的price元素的值须大于15.00 |
/bookstore/book[price>15.00]/title |
选取所有bookstore元素中的book元素的title元素,且其中的price元素的值须大于15.00 |
//title[@*] |
选取所有带有属性的 title 元素 |
如果需要选择一个以上的路径,可以在XPath表达式中使用“|”运算符:
路径表达式 |
描述 |
//book/title | //book/price |
选取所有book元素的title和price元素 |
//title | //price |
选取文档中所有的title和price元素 |
/bookstore/book/title | //price |
选取所有属于bookstore元素的book元素的title元素,以及文档中所有的price元素 |
运算符 |
描述 |
实例 |
| |
计算两个节点集 |
//book | //cd,返回所有带有 book 和 cd 元素的节点集 |
+ |
加法 |
6 + 4, |
- |
减法 |
6 - 4 |
* |
乘法 |
6 * 4 |
div |
除法 |
8 div 4 |
= |
等于 |
price=15 |
!= |
不等于 |
price!=15 |
< |
小于 |
price<15 |
<= |
小于或等于 |
price<=15 |
> |
大于 |
price>15 |
>= |
大于或等于 |
price>=15 |
or |
或 |
price=15 or price=35 |
and |
与 |
price>15 or price<35 |
mod |
计算除法的余数 |
5 mod 2 |
轴名::节点测试[谓语]
其中:
(1)轴(axis),定义某个相对于当前节点的节点集。
示例代码:child::price[price=9.90]
XPath的轴名称 :
轴名称 |
描述 |
ancestor |
选取当前节点的所有先辈 |
ancestor-or-self |
选取当前节点的所有先辈以及当前节点本身 |
attribute |
选取当前节点的所有属性 |
child |
选取当前节点的所有子元素 |
descendant |
选取当前节点的所有后代元素 |
descendant-or-self |
选取当前节点的所有后代元素以及当前节点本身 |
following |
选取文档中当前节点的结束标签之后的所有节点 |
namespace |
选取当前节点的所有命名空间节点 |
parent |
选取当前节点的父节点 |
preceding |
选取文档中当前节点的开始标签之前的所有节点 |
preceding-sibling |
选取当前节点之前的所有同级节点 |
self |
选取当前节点 |