- 浏览: 3638 次
- 性别:
- 来自: 北京
最新评论
-
haohao-xuexi02:
Eclipse配色方案插件 真漂亮 -
YDY20082008:
Eclipse配色方案插件 真漂亮 -
hety.love:
3ks~~~~~~~~~~~~~~~~~~~~~`
Eclipse配色方案插件 真漂亮 -
mjlixm:
Eclipse配色方案插件 真漂亮
Eclipse配色方案插件 真漂亮 -
liangcoder:
good job~
Eclipse配色方案插件 真漂亮
文章标题
f原文链接
1. XSL处理模型
XSL是一个模板语言,而不是一个程序语言。这意味着
stylesheet
制定了一个输出样本,而不是使用程序按步骤生成。一个stylesheet
包含了一个混合的输出样本,并且为每个样本佩戴了输出指令。每一个晓得输出样本加上处理指令就构成了一个模板。
通常情况,你要为文档内的每个元素书写一个模板。这样能够让你每次只专注于一个元素,并持有一个
stylesheet
模块。XSL的强大之处在于它能够递归的处理模板,也就是说,每个模板只处理它对应的一个元素,然后调用其它模板来处理它的子元素,以此类推。一个XML文档总是用一个根元素作为顶层元素,并包含可以嵌套的子元素,XSL模板总是从顶层开始扫描,并照层级来处理元素。
现在用Docbook的
<para>
元素为例子,要把它转换成HTML,你希望使用HTML标记<p>
来包围要输出的内容。但是DocBook的<para>
元素可以包含任何in-line
类型的元素来标记内容;不用担心,你可以让其它对应的模板来处理这些元素,因此你的<para>
XSL模板会是下面这样的简单:<xsl:template match="para"> <p> <xsl:apply-templates/> </p> </xsl:template>
元素
<xsl:template>
表示开始一个新的模板,属性match
声明什么元素要被应用模板,在这个例子中将匹配任何的<para>
元素。模板指出要输出一个<p>
并执行<xsl:apply-template>指令。这将告诉XSL处理器在stylesheet
内寻找所有的模板并将其应用到段落中的元素。如果stylesheet
每个模板都含有一个<xsl:apply-template>
指令,那么将会递归执行下去。当执行到stylesheet
的末尾时,模板将输出一个结束的</p>
标签。 1.1. 重要的上下文环境
既然不需要用线性的步骤来书写你的文档,那么一个用来描述在什么地方应用这些模板的“上下文环境
”
是尤为重要的。大多数模板都提供了一个
match
属性来描述上下文环境,这是一个纯粹的表达式语言:XPath
,用来标识你文档中的哪个部分将被应用这个模板。简单的上下文环境通常只声明一个元素名,就像上面的例子。但是你也可以指定元素的子元素,子元素也可以指定属性值,指定的元素成一个队列的形式,以此类推。下面的模板例子描述如何匹配DocBook的<formalpara>
元素 <xsl:template match= "formalpara" > <p> <xsl:apply-templates/> </p> </xsl:template> <xsl:template match= "formalpara/title" > <b><xsl:apply-templates/></b> <xsl:text> </xsl:text> </xsl:template> <xsl:template match= "formalpara/para" > <xsl:apply-templates/> </xsl:template>
上面定义了三个模板,第一个应用于
<formalpara>
元素本身,另外两个应用其子元素。在第二个模板中的match
属性是一个XPath
表达式,用来表示这里的<title>
元素是一个直接隶属与<formalpara>
元素的子元素。这就区分与在DocBook中的其它<title>
元素。XPath
表达式是控制模板如何应用的关键。 通常情况,XSL处理器的内部规则是在面对高层模板和底层模板时,优先应用底层模板,这里的层次是元素的层级,文档顶层是高层元素,以此类推。这能够让你更细致的控制模板应用,但是在你没有为复杂的符合元素提供细致的上下文环境时,XSL处理器也对其提供了备选方案。这个特性在上面的例子中得以体现,对于
formalpara/para
,例子中提供的第三个模板,<para>
元素作为<formalpara>
元素的子元素,处理器将使用单独的方式来处理它,它将不会再输出已经被父元素输出的<p>
HTML标签。如果formalpara/para
模板没有包含在上面的例子中,那么处理器将使用备选的模板match="para"
,这个模板在上一个例子中定义。这样处理器将输出第二层<p>
HTML标签。 你也可以使用XSL中的
modes
来控制模板上下文环境,这种方式已经被广泛应用与DocBook
stylesheet中。Modes
能够让你使用不同的方式来处理相同的输入。在<xsl:template>
模板定义中使用mode
属性将会为模板指定一个mode
命名。这种情况下,当有两个模板指定了相同的mode
属性值,处理器将把math
的属性值和mode
的属性值通过表达式and
连接来作为一个过滤条件,也就是说,当mode
属性值相同时则继续使用match
属性值匹配来区分使用哪个模板。这就让你对一个元素定义了两个不同的模板来针对不同的上下文环境。例如,下面对DocBook的<listitem>
元素定义了两个不同的模板:
<xsl:template match= "listitem" > <li><xsl:apply-templates/></li> </xsl:template> <xsl:template match= "listitem" mode= "xref" > <xsl:number format= "1" /> </xsl:template>
第一个模板应用于普通的列表输出情况,模板输出
<li>
HTML标签来。第二个模板定义为<xsl:apply-templates select="$target"
mode="xref"/>
,这种情况下用来专门处理<xref>
元素。在这个例子中,mode
属性的值决定应用第二个模板,它将初始带有序号的列表。因为在输出<xref>
元素时经常会有这样的需求。
请记住,
mode
的设置不会自动的贯穿处理子模板<xsl:apply-templates/>
。当子模板含有mode
属性时,你可以有两个选择来处理: -
要想继续使用
mode
模式,也就是使用<xsl:apply-templates mode="mode"/>
模板来处理子元素,处理器将查找具有相同mode
属性值的模板来应用子元素。注意,这样的话你就没有备选方案,如果模板没有指定mode
属性值,子元素将不会有模板匹配,也就不会被模板处理。如果你想使用没有mode
属性的模板作为备选,那么在stylesheet
中加入下面的模板:<xsl:template match= "*" mode= "mode" > <xsl:apply-templates select= "." /> </xsl:template>
这样的话,对于任何子元素,如果模板没有配备mode
属性值,那么模板也将会被应用 -
使用通常的
无mode
模板,对子元素使用<xsl:apply-templates/>
,你可以定义无mode
模板
1.2. 编程特性
尽管XSL是模板驱动的,但是它同样具有很多传统编程语言的特性。下面一些例子来自与DockBook
stylesheet
Assign a value to a variable: <xsl:variable name= "refelem" select= "name($target)" /> If statement: <xsl:if test= "$show.comments" > <i><xsl:call-template name= "inline.charseq" /></i> </xsl:if> Case statement: <xsl:choose> <xsl:when test= "@columns" > <xsl:value-of select= "@columns" /> </xsl:when> <xsl:otherwise> 1</xsl:otherwise> </xsl:choose> Call a template by name like a subroutine, passing parameter values and accepting a return value: <xsl:call-template name= "xref.xreflabel" > <xsl:with-param name= "target" select= "$target" /> </xsl:call-template>
然而你不能像在其它编程语言那样来使用上面这些结构,因为
变量
在特别的情况下会具有完全不同的行为。 1.2.1. 使用变量和参数
XSL提供两种元素来让你指派值到变量上:
<xsl:variable>
和<xsl:param>
。它们享用共同的命名空间和语法,都使用$name
来引用变量。这两个元素最主要的不同是param's
的默认值能够被模板调用的<xsl:with-param>
所取代,就如上面最后一个例子所示。
下面两个例子同样来自DocBook:
<xsl:param name= "cols" > 1</xsl:param> <xsl:variable name= "segnum" select= "position()" />
在上面两个元素中,
param
和variable
的名字都是通过name
属性来指定的,可以看到param
的名字是cols
,variable
的名字是segnum
。它们的值可以通过两种方式来提供,参数的例子是通过元素的内容值“1
”
来赋值的,而变量的例子是通过select
属性值来赋值的,这个属性值是一个表达式的结果,而元素本身并没有内容值。
对于新接触XSL的用户来说变量的特性有点古怪,当你给一个变量赋值后,你就不能在它的应用周期内改变它的值,如果这样做会报错。所以你不能像在使用其它编程语言那样对变量进行动态存储,变量在它的应用周期内持有的是固定值,并在应用周期结束时销毁。这个特性是在设计XSL时就决定了,因为XSL是模板驱动而非流程驱动的。这意味着它没有固定的执行顺序,所以你无法依赖一个能够改变值的变量。要想正确的使用变量,你必须理解变量的周期是如何定义的。
如果一个变量定义在所有模板的外部,那么它就被认为是一个全局变量,它对所有模板都生效。全局变量的值是固定不变的,也不能被任何模板所重新赋值。但是你可以在模板内创建一个与全局变量同名的本地变量,然后赋予其它的值。本地变量只能在其自己的应用周期内起作用。
定义在模板里的本地变量只会在它被允许的周期内生效,也就是对在它之后的同胞和后裔有效。要想理解这个周期,你必须明白XSL指令其实就是纯粹的XML元素,并内嵌在XML家族层级结构中。它们通常是指父级、子级、同级、祖先级和后裔级。在XML家族层级中,给一个变量赋值就像发布一个公告给你希望听到家族成员一样。你只能把公告发布给比你年龄低的同级(包括你自己)和它们的后裔级,也就是说定义在你前面的年长的同级将不会听到公告,更不用说你的父级和祖先了。如果你发布不同的公告内容但是用相同的公告名给相同的被通知成员,那将出现错误,(言外之义,你重新给变量赋值了)。请记住这里的家族并不是你的文档元素,而只是在你
stylesheet
中的XSL指令。手工编写stylesheet
将对你跟踪周期很有帮助,XSL元素缩进和嵌套将帮助你理解周期。下面的代码片段来自DocBook
stylesheet中的pi.xsl
文件,举例说明两个变量周期的不同。
1 <xsl:template name= "dbhtml-attribute" > 2 ... 3 <xsl:choose> 4 <xsl:when test= "$count>count($pis)" > 5 <!-- not found --> 6 </xsl:when> 7 <xsl:otherwise> 8 <xsl:variable name= "pi" > 9 <xsl:value-of select= "$pis[$count]" /> 10 </xsl:variable> 11 <xsl:choose> 12 <xsl:when test= "contains($pi,concat($attribute, '='))" > 13 <xsl:variable name= "rest" select= "substring-after($pi,concat($attribute,'='))" /> 14 <xsl:variable name= "quote" select= "substring($rest,1,1)" /> 15 <xsl:value-of select= "substring-before(substring($rest,2),$quote)" /> 16 </xsl:when> 17 <xsl:otherwise> 18 ... 19 </xsl:otherwise> 20 </xsl:choose> 21 </xsl:otherwise> 22 </xsl:choose> 23 </xsl:template>
变量
pi
的周期开始于第8行,也就是模板定义它的位置,结束于第20行它最后一个同级兄弟结束的地方[1
]
。变量rest
的周期开始于13行,结束与15行。幸运的是,15行的输出表达式赶在周期结束前使用了变量值。
让我们来看看当在变量的周期内使用
<xsl:apply-templates/>
会如何?被应用的模板内会得到变量值吗?答案是否定的。因为被应用的模板生效周期并没有真正的在变量周期内,它在stylesheet
的其它地方退出,并不是在变量的低龄同级和后裔内退出。
要想传值给一个模板,你可以使用
<xsl:with-param/>
传递一个参数。这种参数传递通常被用在使用<xsl:call-templates/>
调用指定模板,尽管你也可以使用<xsl:apply-templates/>
调用模板,但是通常被调用的模板希望传入一个与<xsl:param/>
定义同名的参数。这样就可以在模板内使用这个参数值。任何传入的参数名如果在模板内没有被定义将被忽略处理。
下面参数传递的例子来自
docbook.xsl
:
<xsl:call-template name= "head.content" > <xsl:with-param name= "node" select= "$doc" /> </xsl:call-template>
上面一个命名为
head.content
的模板被调用,在调用周期内传递了一个名为node
的参数,参数值是变量$doc
。上面被调用的模板看上去会是下面的样子: <xsl:template name= "head.content" > <xsl:param name= "node" select= "." /> ...
模板期望一个参数是因为模板定义中声明了一个
<xsl:param/>
,并且名字和传入参数名相同。模板内的<xsl:param/>
提供了一个默认值,如果传入的参数名没有与其匹配,那么将在模板内使用默认值。
1.3. 生成HTML
从你的DocBook文件生成HTML需要使用HTML版本的
stylesheet
,这些由stylesheet
的HTML驱动文件docbook/html/docbook.xsl
来完成。这是一个主stylesheet
文件,它使用<xsl:include/>
导入其它组件文件组装一个完整的stylesheet
用来生成HTML DocBook
stylesheet生成HTML的方式是通过应用模板来输出一些文本内容和HTML元素的混合体。从
docbook.xsl
的顶层开始: <xsl:template match= "/" > <xsl:variable name= "doc" select= "*[1]" /> <html> <head> <xsl:call-template name= "head.content" > <xsl:with-param name= "node" select= "$doc" /> </xsl:call-template> </head> <body> <xsl:apply-templates/> </body> </html> </xsl:template>
模板匹配到你输入文档的根元素,然后就开始递归应用模板。首先定义了一个变量
doc
,然后输出两个HTML元素<html>
和<head>
。接着调用名为head.content
模板来处理HTML的<head>
,关闭<head>
后就开始<body>
。这里使用<xsl:apply-templates/>
来递归处理输入文档中的内容,最终关闭像HTML文件的输出。
简单的HTML元素可以用不带任何属性的元素生成,如
<html>
,但是如果HTML元素输出依赖上下文环境,你就需要一个强大的机制来选取输出元素并且还会生成它们的属性和属性值。下面的代码片段来自于sections.xsl
,其展示了用<xsl:element>
和<xsl:attibute>
来生成HTML的头标签
1 <xsl:element name= "h{$level}" > 2 <xsl:attribute name= "class" > title</xsl:attribute> 3 <xsl:if test= "$level < 3" > 4 <xsl:attribute name= "style" > clear: all</xsl:attribute> 5 </xsl:if> 6 <a> 7 <xsl:attribute name= "name" > 8 <xsl:call-template name= "object.id" /> 9 </xsl:attribute> 10 <b><xsl:copy-of select= "$title" /></b> 11 </a> 12 </xsl:element>
整个例子生成了一个单独的HTML头元素。第1行定义了一个HTML元素,例子中元素的名字是一个带有变量
$level
的表达式,变量是通过参数出入模板的。这样的话模板就会生成<hi>
、<h2>
、等等。具体生成哪个依赖于上下文环境。第2行为头元素添加了一个属性class="title"
。第3-5行添加了属性style="clear
all"
,但是只适用于头元素的层级数小于3的情况。第6行打开一个锚元素<a>
。看上去没带有任何属性,其实是在第7-9行为<a>
元素添加了name
属性。这个例子描述XSL管理的输出元素是一个活的元素,而不只是一个文本串。第10行输出头元素的标题文本,同样是通过传递参数的形式获得,然后关闭HTML粗体标签。第11行使用</a>
关闭锚标签,第12行是头元素的关闭标签,这就结束了头元素的定义。
当你随着模板的递归来处理元素时,可能会疑惑在你文档里的内容文本是如何被模板输出的,在
docbook.xsl
文件中你会找到如下的模板,它专门用来内容文本。
<xsl:template match= "text()" > <xsl:value-of select= "." /> </xsl:template>
这个模板的主体由文本节点的值组成,它只是文本。通常,如果你的
stylesheet
中没有提供匹配的模板,XSL处理器都有一些内建的模板来获取内容文本。上面的模板就是提供这样的功能,只不过它明确定义在stylesheet
文件中。 1.4. 生成格式化对象(FO)
使用
fo
版本的stylesheet
可以把你的DocBook
XML生成格式化对象。这里需要在你的stylesheet
中使用docbook/fo/docbook.xsl
。在你的主stylesheet
文件中使用<xsl:include>
引入所有的组件组装成完整的stylesheet
来生成格式化对象。生成格式化对象只完成了输出过程的一半,你还需要使用XSL-FO
处理器,比如FOP。 DocBook的fo stylesheet和HTML
stylesheet的工作方式类似,就是用
<fo:something>
形式的标签代替相应的HTML标签。例如,输出in-line
类型并且使用monospace
字体,fo的形式会是如下的样子: <fo:inline-sequence font-family= "monospace" > /usr/man</fo:inline-sequence>
输出一个DocBook
<filename>
元素,在docbook/fo/inline.xsl
中的模板定义看起来像如下的样子: <xsl:template match= "filename" > <xsl:call-template name= "inline.monoseq" /> </xsl:template> <xsl:template name= "inline.monoseq" > <xsl:param name= "content" > <xsl:apply-templates/> </xsl:param> <fo:inline-sequence font-family= "monospace" > <xsl:copy-of select= "$content" /> </fo:inline-sequence> </xsl:template>
在XSL标准中指定了很多XSL-FO标签和属性的规范,要描述在DocBook中如何遵循这些规范显然已经超出本书的范围。庆幸的是,这些只是中间格式,你不许要马上去处理,除非你正在自己编写
stylesheets
。
相关推荐
XSL-Stylesheets Source: DocBook-XSL-1.79.1
DocBook 是一个流行的XML文档格式,它用于编写技术文档,如手册、教程、参考指南等。这个"docbook-xsl-1.73.2.zip"压缩包包含的是DocBook XSL样式表的1.73.2版本,这是一个关键组件在将DocBook XML文档转换成各种...
适用于想要使用DocBook XSL样式表发布DocBook XML文件的人员的指南。 提供访问DocBook的全部功能所需的详细信息。
标题“docbook-style-xsl.zip”表明这是一个包含DocBook风格XSL转换文件的压缩包。DocBook是一种XML架构,常用于编写技术文档,如手册、教程和参考指南。它允许内容作者专注于文档的内容,而不是排版,然后通过XSL...
在IT领域,DocBook是一种广泛应用的XML文档格式,用于编写技术手册、书籍、教程等技术文档。它提供了一种结构化的语言来描述内容,而XSL(eXtensible Stylesheet Language)则用于转换这些结构化数据,将它们呈现为...
asciidoctor-fopub, 可以移植的DocBook到PDF构建命令,它包装 DocBook XSL和 asciidoctor-fopub使用自由软件实现DocBook-to-PDF转换 ! ( 基于 DocBook XSL和 Apache FOP )可以使用 asciidoctor fopub项目将任何...
1 docbook-xsl-ns-1.75.2.zip解压到D:\docbook 2 另外四个压缩包解压出来,把里面的bin,include和lib三个文件夹拷贝到D:\docbook\xsltproc目录下 2 环境变量Path中增加 D:\docbook\xsltproc\bin 3 新建一个bat,...
《dbcookbook》是关于DocBook和DocBook XSL样式表的一个实用资源,它为XML文档处理提供了一系列的“食谱”,旨在帮助用户更高效、更便捷地利用这些技术进行技术文档的编写和格式化。这个压缩包文件“dbcookbook-...
DocBook XSL Configurator 是一个包含三个 Java (Swing) 应用程序的伞形项目,用于创建 DocBook XSL 自定义层(FO、HTML 和 Manpages),然后执行外部子流程以转换 DocBook XML 并查看输出。
XSL-Stylesheets Document: DocBook-XSL-1.79.1
docbook-style-xsl-1.75.2-6.el6.noarch.rpm
3. **安装 Docbook XSL 样式表**:这是实现 Docbook 文档转换的核心工具,可以在官方网站上获取。解压下载的文件,并将解压后的目录路径加入到系统 PATH 环境变量中。 4. **安装 XML 编辑器**:推荐使用 Oxygen XML...
docbook2asciidoc, 将DocBook转换为AsciiDoc的XSL 这是将 DocBook 4.5转换为 AsciiDoc插件的样式表,最初由 bjepson 启动。依赖项这个项目有一个模块 ( https://github.com/oreillymedia/docbook2htmlbook ) 。
离线安装包,亲测可用
DocBook到LaTeX XSL样式表是一套开源工具,用于将使用DocBook XML格式编写的文档转换为LaTeX源代码。DocBook是一种广泛使用的结构化文档格式,特别适合技术写作,如手册、教程和API文档。它允许作者关注内容,而不是...
- **DocBook套件**:如DocBook XSL样式表,包含预定义的转换规则。 4. ** windows-docbook-config.pdf**: 这个文件可能是Windows环境下配置DocBook环境的指南,可能涵盖了安装XML工具链、配置环境变量、设置...
离线安装包,亲测可用
离线安装包,亲测可用
DocBook 是一种结构化的 XML 格式,常用于编写技术文档,如用户手册、软件文档、教程等。它提供了一套严谨的标记语言,使得内容的结构清晰,易于自动化处理和发布。这篇“docbook使用心得”博文链接分享了作者在使用...
DocBook是一种XML(可扩展标记语言)文档格式,专门用于编写技术文档,如用户手册、教程、参考指南等。这个压缩包包含两份资源:"docbook - the definitive guide.chm" 和 "Writing documentation using DocBook.pdf...