无废话XML阅读笔记(四)

无废话XML阅读笔记(四)
2008年6月8日
六.XSLT-XML 专属的转换语.
        这章的重点是XSLT.要谈XSLT,得先从XSL谈起.
        1. 另一种样式-XSL简介.
                XSL(eXtensible Stylesheet Language)是专门为XML设计的样式,也是在CSS之外,另一个替XML穿戴打扮的选择.它一共分作两部分:第一部分负责将XML源代码转换为另一种格式,而第二部分(称作"FO" [Formatting Object;打样物件])则提供了大量的打样命令,可用来配合印刷或屏幕显像,精确地设定外观样式(如:字的大小,摆放的位置等),是一种所谓"device-independent"格式.第一部分的转换语法,可以用来为第二部分服务,将XML文件变形为打样命令.XSL的转换语法,并不限于将XML转成FO命令.事实上,XSL可以输出任何格式正确的XML文件.因为这个特性,我们可以用它来做以下几种形式的转换.
                XML-->HTML 这是最常见的一种转换.转换出来的HTML文档,在格式上因为已经达到了格式正确的要求,在本质上非常接近XHTML.
                XML-->XML  把一种格式的XML文件转换成另一种XML格式.有非常大的使用价值.例如:两个机关或企业之间以XML来传递信息,如果彼此使用XML格式有出入,可以用XSL来做调整.
                XSL-->XSL  XSL甚至可以将一个样式转换成另一种样式.(因为XSL,本身也就是XML的一个应用,所以XSL-->XSL在本质上不过是XML-->XML的一个特例而已).
                (1). XSL和CSS不同的地方.
                XSL采用的是转换的方式,将一种格式的XML,转换为另一种.而CSS则来自完全不同的理念:它不含任何转换动作,只针对XML文件中各个成分的外观属性一一加以设定.另一个区别是:XSL样式都是XML文件,完全照XML的语法来;相对地,CSS在语法上自成一个,和XML的写法大相径庭.
                (2). XSL和CSS相同的地方.
                XSL和CSS都属于样式表的一种.样式表是用设定外观的,它并不影响原来的XML源代码.XSL虽然用的是转换的方式,但是"转换"并不代表源代码遭到篡改.通常XSL转换后的输出码,是另存到一个新的档案,或暂存在浏览器的记忆体中.原来的XML档案内容保持不变.
        2.XSLT入门.
                (1). XSLT在网络上的应用模式.
                        Server端XML文件在下载到浏览器之前,先以XSLT转为HTML.
                        [1]. 动态即时产生: 在浏览器向Server送请求的时候,以XSLT处理软件将XML立即转换为HTML,送出.在网页中有动态资料要即时插入,或当XML文件是从数据库即时取的场合下,最适合这种运作模式.
                        [2]. 批次产生:如果XML文件事先都写好,一一存放在档案里,而非即时取得,或者随时不断更新,我们便可以用批次转换的做法,事先将HTML准备好.转换的工作则可以依据实际需要,在固定的时段自动化执行.这么做的好处是让Server资源可获得最大的节约.
                        Client端 如果浏览器直接支持XML和XSLT,XML源码和XSLT样式便可以以图像档一样,让浏览器直接下载下去,一切转换的工作由浏览器代劳.
                (2). XSLT的转换流程以及工作原理.
                        XSLT转换必须由特别的软件来担任,这样的软件,统称为XSL处理器(XSL processor).在XSL处理器在工作之前,得先借XML解析器(内置或外部),替它把XSL样归和XML文件中的一个个物件和结构分析出来.
                        在XSLT中,有两个重要的观念,一个是源树(source tree),指的是转换前的XML文件的结构;另一个是结果树(result tree),代表转换的成品,结构依然是XML.XML处理器启动时,会先叫XML解析器替它解析XSL样式和要转换的XML文件.在掌握了样式中的各个XSL命令后,XSL处理器便开始依照样式的指示,在源树上"爬来爬去",一遇到合适的枝叶,就按样式的设定,吐出一段新枝叶(一个XML片段),一直到整颗树都走遍为止.有的时候,样式会指示处理器,将枝叶先修正一下再吐出来.所以经由XSL处理起一路产生的新枝叶,统统加到一块,就成了一株结果树.结果树可以输出到档案里储存起来,或者由浏览器显示在屏幕上.
                (3). 支援XSL的软件.
                        支援XSL的软件,可粗略分为浏览器和转换工具(IBM AlphaWorks实验室出品的LotusXSL 和XSLT作者James Clark所写的xt)两类.在处理XSL时,尽量使用xt作为转换工具.在性能,速度,正确度和标准的支援程度上,xt都是很好的支持.
        3. 细谈XSLT.
                XSLT的语法和运行的方式有些诡异,可能需要一些时间才能渐渐适应.
                (1). 成品预览.
                <?xml version="1.0" encoding="gb2312"?>
                <?xsl-stylesheet type="text/xsl" href="search_result.xsl"?>
                <产品搜索>
                        <摘要>搜寻字符串:"滑鼠 键盘", 共找到2笔</摘要>
                        <产品>
                                <货号>00011</货号>
                                <品名>手不痛牌鼠标</品名>
                                <定价>$234</定价>
                                <说明页 网址="
http://www.keona.cn/mouse/12345">上市发表会</说明页>
                        </产品>
                        <产品>
                                <货号>00022</货号>
                                <品名>打的响牌键盘</品名>
                                <定价>$567</定价>
                                <说明页 网址="
http://www.keona.cn/key/654321">产品特性</说明页>
                        </产品>
                </产品搜索>
                透过XSLT我们可以将上面的XML码,转换成下面的HTML格式.
                <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
                <html>
                        <head>
                                <title>产品搜索结果</title>
                                <META http-equiv="Content-Type" content="text/html; charset=GB2312">
                        </head>
                        <body>
                                <h1>产品搜索结果</h1>
                                <p><b>摘要:</b>搜索字符串:"滑鼠 键盘", 共找到2笔</p>
                                <table>
                                        <tr>
                                                <th>品名</th><th>定价</th><th>说明页</th>
                                        </tr>
                                        <tr>
                                                <td>手不痛牌鼠标</td><td>$234</td>
                                                <td><a href-"
http://www.keona.com/mouse/12345">上市发表会</a></td>
                                        </tr>
                                         <tr>
                                                <td>打的响牌键盘</td><td>$567</td>
                                                <td><a href-"
http://www.keona.cn/key/654321">产品特性</a></td>
                                        </tr>
                                </table>
                        </body>
                </html>
                以上的HTML代码为xt的实际输出结果.整个转换过程真正的主角,就是下面的XSLT代码.
                <?xml version="1.0" encoding="gb2312"?>
                <xsl:stylesheet version="1.0"
                                xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
                <!-- IE5只 接受
                        <xsl:stylesheet xmlns:xsl="
http://www.w3.org/TR/WD-xsl"> -->
                <!-- IE5看不懂xsl:output -->
                <xsl:output encoding="GB2312" />
                <xsl:template match="/">
                        <html>
                                <head>
                                        <title>产品搜寻结果</title>
                                </head>
                                <body>
                                        <h1>产品搜寻结果</h1>
                                        <p><b>摘要:</b><xsl:value-of select="*/摘要/"></p>
                                        <xsl:apply-templates select="产品搜寻" />
                                </body>
                <xsl:template>
                <xsl:template match="产品搜寻">
                        <table>
                                <tr><th>品名</th><th>定价</th><th>说明页</th></tr>
                        <xsl:for-each select="产品">
                                <tr>
                                        <td><xsl:value-of select="品名" /></td>
                                        <td><xsl:value-of select="定价" /></td>
                                        <td><a href="{说明页/@网址}"><xsl:value-of _fcksavedurl=""{说明页/@网址}"><xsl:value-of" _fcksavedurl=""{说明页/@网址}"><xsl:value-of" _fcksavedurl=""{说明页/@网址}"><xsl:value-of" _fcksavedurl=""{说明页/@网址}"><xsl:value-of" _fcksavedurl=""{说明页/@网址}"><xsl:value-of" _fcksavedurl=""{说明页/@网址}"><xsl:value-of" select="说明页" /></a></td>
                                </tr>
                        </xsl:for-each>
                        </table>
                </xsl:template>
                </xsl:stylesheet>
                (2). XSL样式与名称空间.
                        如同其他许多XML的应用,XSLT大力仰仗命名空间所提供的机制,把XSLT命令和其他XML标注隔开.样式所有的XSLT命令,都必须标明是隶属于"
http://www.w3.org/1999/XSL/Transform"这个XSLT专用的命名空间,才能正常的工作.
                        在声明XSLT的名称空间时,最常见的做法是以"xsl"作为前置字符串.
                        <xsl:stylesheet xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" version="1.0">依照规定,所有的XSLT命令必须置于<xsl:stylesheet>..</xsl:stylesheet>区块里.也就是说,xsl:stylesheet这个元素界定了XSLT样式的内容;因为它是最外层的元素,命名的声明,自然也就摆在这个元素的标签里.在1999年的10月8日版的XSLT标准中,xsl:stylesheet又增加了一个不可省略的属性:version,用来标示样式所遵循的XSLT的语言版本.所有的XSLT命令,一律使用xsl作为前置字符串.
                (3). XSLT运行细节.
                        XSL处理器按照样式的设定,在源树上寻找合适的节点,并适时产生新枝叶.这个样式的设定,在XSLT中正式称呼叫做"模板式(template ruels)".XSL处理器就是根据这些式子来寻找节点,产生新码的.
                看个实例:
                <?xml version="1.0" encoding="GB2312"?>
                <xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
                <xsl:output encoding="GB2312" />
                <xsl:template match="/">
                <html>
                        <p>一个很空洞的模板,不怎么来劲!</p>
                <html>
                </xsl:template>
                </xsl:stylesheet>
                这是一份完整的XSL样式,里面只有一个模板式.我们看到,模板式以xsl:template这个元素来定义,该元素所包含的内容,不意外,正是XSLT中所谓的[模板(template;黑色文字)].xsl:template里面有个match="..."的属性,XSL样式正式借着这个属性,来告诉XSL处理器,该去找什么样的节点.在例子中,模板式指定对应的节点是"/",也就是在源树最顶层的跟元素.
                XSL处理器在启动时,会先将所有列在样式中的模板式看过一遍,并牢记在心,然后便开始检视源树,而且肯定先从"/"(跟元素)下手,每对应到一个节点,就把相关的模板式的模板抄一份出来,加进要输出的文件里.
                事实上,match的属性值不限于使用确切的节点名,其实它是一个对应式(pattern),有一套完整的语法,可用来选择样规里各个模板式对应到的节点.
                还有要请注意的一点:模板的内容,必须是格式正确的XML片段,XSL掩饰的设定内容,是先经过XML解析器解析,然后才交给XSL处理器,因此,如果样式里有任何一段违背格式正确的原则,整个转换过程会再XML解析器那关就宣告失败.
                当前节点和语境:
                XSLT处理器会爬树,从这个节点爬到那关节点.每到一个新的节点,XSLT处理执行命令的语境(context)就跟着改变.这个新到的节点,在XSLT中的术语叫"当前节点(current node)",即处理器当时所在的节点.
                当前节点应用实例---xsl:value-of;
                XSL模板中的内容,除了能让XSL处理器一五一十的照抄,输出之外,还可以透过XSLT命令,对资料做排列,组合等处理.
                <xsl:value-of ... />就是一个常用的XSLT命令,它通常是用来读取源树中某元素所包含的文字内容,或者是某个属性的值.标签中肯定要附上一个select属性.如同<xsl:template>中的match属性,在<xsl:value-of select=".." />里,select属性后面接的,也是对应式.XSLT对应式在对应的时候,以当前节点作相对位置的轴点.星号"*"会对应到位于当前节点下一层的所有元素的节点;换句话说,就是所有当前节点所在的元素的子元素."/"在对应式语法中是用来分隔节点层级的,就像/在网址和Unix系统中用来界定目录一样.合起来,"*/摘要"会对应到一个名叫"摘要"的元素节点,它的母节点刚好是当前节点的子元素节点.(该元素是空元素,请勿忘记<xsl:value-of .../>)
                语境转移.
                让当前节点层层下移.有两个XSLT命令-- xsl:apply-templates 和 xsl:for-each 可以用来达到这个目的,转移当前节点的位置.
                模板套入-- xsl:apply-templates.
                <xsl:apply-templates select="产品搜寻" />中有一个select对应式,这个命令告诉XSL处理器:把select对应到的各个节点一一当成是当前节点,并依次处理这些节点的模板.当<xsl:apply-templates>中的select属性省略时,XSL处理器则会以所有的现节点的子元素作为处理对象.(该元素是空元素,请勿忘记<xsl:apply-templates .../>).
                <xsl:apply-templates .. />的出现,让转换流程起了变化.XSL处理器在这里转弯,先去执行其他的模板式,并且将产生的结果由<xsl:apply-templates .../>这点插入,一直到所有对应到的模板式都执行完毕,最后才回来执行原来的模板中剩下的部分.
                xsl:for-each循环.
                xsl:for-each是另一个会改变现节点和语境的命令.和xsl:apply-templates一样,xsl:for-each后面也有一个select对应式,用来选择心得现节点.在XSLT中,select对应式所对应到的节点不见得只有一个,而可能有好几个;如果不只一个,XSL处理器会按照他们在XML源代码中的顺序来一一处理.
                (4). 属性值模板.
                被大括号{}括起来的属性值时(<a href="{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" _fcksavedurl=""{说明页/@网址}">123</a>),XSL处理器会把大括号中的区域,当作是属性值模板(attribute" value templates)来处理.我们可以把属性模板想成是一个迷你模板.
                "@",在XSLT中是用来对应属性名的.
                (5).输出文字编码设定.
                1999年8月13日版,XSLT草案中新增了一个xsl:output的命令,专门用来设定输出码的各项特性,如字符编码,缩排等.xml:output 中有一个encoding的属性,可以用来控制输出的字符编码.
        4.XPath路径描述语.
                XPath的目的是提供XSLT和XPointer(XML文件内部连接语)一个共同,整合的对应法,用来对应XML文件的各个部分,选择文件中的构成原件(元素,属性,文字内容...).
        对应式                        说明
        -----------------------------------------------------------------------------------------------------------------------------------------
        某元素                        对应到当前节点下所有名为[某元素]的子元素.
        *                             对应到当前节点下的所有子元素.
        */某元素                      对应到当前节点开始算起,所以名为[某元素]的孙节点.
        @某属性                       对应到一个附属于现节点,名为[某属性]的属性.
        @*                            对应到所有附属于现节点的属性.
        text()                        对应到当前节点的子元素中所有文字节点.
        .                             对应到当前节点.
        ..                            对应到当前节点的上一级.
        某元素[1]                     对应到当前节点下,第一个叫做[某元素]的子元素.
        某元素[position()=1]          作用同上.
        某元素/[@某属性="谋值"]       对应到当前节点下所有名为[某元素]的子元素,这个子元素必须含有一个[某属性]的属性,其属性值必须为[某职].
        元素甲|元素乙                 对应到当前节点下,所有名为[元素甲]和[元素乙]的子元素;|代表[或]的关系.
        .//后世子孙                   对应到当前节点下,所有名为[后世子孙]的元素;//符号代表可跨越数级.
        祖宗//徒孙                    对应到所有名为[徒孙]的元素,他们的上级必须是有一个叫[祖宗]的元素,而且[祖宗]还得是现节点的一个子元素.
        5.迁就IE5
                (1). IE5命名空间的差异:
               
http://www.w3.org/TR/WD-xsl(IE5)      http://www.w3.org/1999/XSL/Transform(如今的).
                (2). IE5不支持xsl:output.
                (3). IE5不支持属性模板.
六.DTD--XML语汇的定义.
        1. 元素类别的声明.
                例子:
                <!ELEMENT 名称 (#PCDATA)>
                <!ELEMENT 作者 (#PCDATA)>
                <!ELEMENT 售价 (#PCDATA)>
                很明显地,ELEMENT之后放的是元素名,接着是它的[内容模型](也就是定义<元素>xxx</元素>之间xxx区域可以出现什么样的内容),#PCDATA是XML中预先定义好的标记,代表Parsable Character Data,即可解析的文字资料.
                (1). 量子学.
                DTD,一如在正规的表达式中,有所谓的量子(量词)最常用的有[?],[*],[+].
                [?]:代表可有有零个或者一个. 0~1;
                [*]:代表有多个(无限制)都可以. 0~无限;
                [+]:代表至少必须有一个,但没有限制. 1~无限;
                备注:DTD中的[?],[*],[+],[,]都是ASCII字符(半型)不要误用了中文的全型符号.
        2.属性类别的声明.
                在DTD中属性是<!ATTLIST..>来声明,ATT就是属性attbute的简写.
                如:
                <!ATTLIST 售价
                                货币单位(人民币|美元|港币) '人民币'>
                最重要的是[货币单位]这行(称为[属性定义])共有三个要件.很明显地第一个是属性名,第二个是属性类别,最后是预设值或预设行为的描述(默认属性).如果属性不只一个的话,这样三个要件单元可以以每三个三个这样重复下去.
        3. 统统放到一起--文件类别声明.
        上面的元素,属性宣告一一设计好后,我们可以开始把他们整理起来,做成一个完整的DTD,并且把它和我们先前的XML文件连接在一起.有两种连接方式可以使用:一是外接,二是内嵌.如果用外接,我们只要将刚才写好的DTD,存到一个后缀名为.dtd的纯文字档中就可以.再配合:
        <?xml version="1.0" encoding="GB2312"?>
        <!DOCTYPE 推荐丛书 SYSTEM "book.dtd">
        这样的链接方式,就可以了.我说[连接],是因为如果这个DTD文档不再同一台机器的同一个目录地下,则必须明确标明网址,而不能只写档案名,路径,否则会找不到.
        或者,我们把DTD直接内嵌在XML文件中.这需要用到<!DOCTYPE ..>的声明,写法上有点CDATA区的感觉,像这样:
        <!DOCTYPE 推荐丛书 [
                <!ELEMENT 推荐丛书 (书籍*)>
                ...
        ]>

 

        好了,到这里<<无废话XML>>的阅读笔记都整理完了,个人觉得<<无废话XML>>整体写的还是可以的,形象的举例.和网络式语言的调侃,让人在不知不觉的感觉上,渐渐熟悉了XML,但是由于台湾和国内的关系,很多专业术语都不一样,看起来的时候如果没有接触过XML的朋友可能会比较难看.不过,我还是在做笔记的时候注意到了这个问题,尽可能把它"翻译"过来了. 说老实话XML在目前开发中也起着十分重要的地位.如果你搞J2EE的,我建议你一定要牢牢的掌握这门知识.因为在J2EE领域中很多都用到了XML语言.如果你有了这个基础,相信再以后的J2EE道路上,你会走的更远更好.!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值