对象
XML教程
可扩展的样式语言(Extensible Style Language,XSL)的第二部分是格式化语言。这是XML应用程序,用来描述如何将内容显示给读者。一般地说,样式单使用XSL转换语言,将XML文档转换成使用XSL格式化对象符号集的新的XML文档。当许多人希望Web浏览器将来的某一天能够了解如何直接显示用XSL格式化对象来标记的数据时,目前就需要有其他措施,使输出文档进一步转换成其他的某个格式,如PDE。
本章的主要内容如下:
* 理解XSL格式化语言
* 格式化对象及其属性
* 对页面进行格式化和设置样式
* 在文本中插入规则
* 在显示的文档中嵌入图形
* 与URI目标的链接
* 在文本中插入列表
* 替换字符
* 使用序列号
* 脚注
* 浮动
* 理解如何使用XSL格式化属性
15.1 XSL格式化语言概述
XSL格式化对象提供了比HTML+CSS(甚至CSS2)更为高级的可视化布局模型。XSL格式化对象所支持但HTML+CSS不支持的格式化包括非西方布局、脚注、页边距注解、交叉引用中的页号等等。特别是,虽然CSS主要用于Web,但XSL格式化对象的用途更为广泛。例如,能够编写使用格式化对象来编排整个打印稿的XSL样式单。不同的样式单能够将同一个XML文档转换到Web站点中。
有关格式化语言的警告语
XSL仍处于开发中。过去XSL语言已经发生了本质上的变化,并且将来仍将发生变化。本章是根据1999年4月21日XSL规范草案(第四稿)编写的。当读者阅读本书时,XSL的这一草案很可能已经被取代,而且XSL原来的句法已经改变。即便如此,本规范的格式化对象部分甚至也没有转换语言规范那样完善。如果确实遇到不能完全正常运行的情况,应将本书中提供的实例与最新的规则加以比较。
糟糕的是,仍然没有任何软件能实现1999年4月21日的XSL规范草稿的所有内容,甚至只对格式化对象这部分也没有任何软件能够实现。实际上,到目前为止,只有James Tauber的FOP,才能部分地执行XSL格式化对象,它使用XSL格式化对象来将XML文档转换成PDF。还没有任何Web浏览器可以显示用XSL格式化对象编写的文档。
当然,随着此项标准向最终版本改进时,当开发商实现XSL格式化对象时,这种情况最终是可以得到修正的。在那之前,我们不得不面对这样的选择:要么忍痛使用目前不完善的、未完成的XSL,并且试图避开遇到的所有程序错误和疏忽,要么使用更确定的技术(如CSS),直到XSL更加可靠为止。
15.2 格式对象及其属性
XSL格式化对象元素正好有51个。在这51个元素当中,大多表示各种类型的矩形区域。其他的大部分都是矩形区域和空间的容器。下面以字母顺序编排,列出这些格式化对象:
* bidi-override
* block
* character
* display-graphic
* display-included-container
* display-rule
* display-sequence
* first-line-marker
* float
* flow
* footnote
* footnote-citation
* inline graphic
* inline-included-container
* inline-rule
* inline-sequence
* layout-master-set
* list-block
* list-item
* list-item-body
* list-item-label
* multi-case
* multi-properties
* multi-property-set
* multi-switch
* multi-toggle
* page-number
* page-number-citation
* page-sequence
* region-after
* region before
* region-body
* region-end
* region-start
* root
* sequence-specification
* sequence-specifier-alternating
* sequence specifier repeating
* sequence-specifier-single
* simple-link
* simple-page-master
* static-content
* table
* table-and-caption
* table-body
* table-caption
* table-cell
* table-column
* table-footer
* table-header
* table-row
XSL格式化模型是基于称之为区域(area)的矩形框,该区域包含有文本、空格或其他格式化对象。尽管CSS页边距被XSL的缩进所代替,但正如CSS框一样,每个区域在其各侧都有边框和贴边。XSL格式化程序读取格式化对象来确定将哪个区域放在页面的什么位置。许多格式化对象都会产生单一的区域(至少对大多数情况即是如此),但由于页面分隔符、单词折行、断字以及将可能存在的不确定量的文本填充到有确定区域中的其他方面的原因,一些格式化对象偶尔也确实产生多个区域。
含有间隔的框与含有空白字符的框是不一样的。含有空间的框是指页面或屏幕上的实际空的区域,例如,页面的左和右边上的页边距。这与页面上单词间的空格字符是不同的。
格式化对象主要在它们所包含的内容上有差别。例如,list-item-label格式化对象就是一个包含项目符号、数字或放在列表项之前的其他指示符的框。list-item-body格式化对象就是一个包含列表项的文本(无标签)的框。而list-item格式化对象就是一个包含list-item-label和list-item两个格式化对象的框。
格式化对象可进一步分成四类不同的矩形区域:
1.区域容器
2.块区域
3.行区域
4.内联区域
这四种类型的区域就形式了粗略的层次关系。区域容器包含其他更小的区域容器以及块区域。块区域又包含其他块区域、行区域和内容。行区域包含内联区域。内联区域包含其他内联区域和内容。所以,更具体地分为:
* 区域容器在XSL中是最高级别的容器。在包含它的区域内,可以精确的坐标加以定位。它既可以包含其他更小的区域容器,也可包含一系列的块区域和显示空间。可以将书的一页看作为区域容器,而这个区域容器包含五个其他区域容器:页眉、页的主体内容、页脚以及左和右页边距(在本例中,页边距区域无内容)。产生区域容器的格式化对象包括region-body、region-before、region-after、region-start和region-end。
* 块区域代表块级元素,如段落或列表项。尽管块区域可能包含其他块区域,但在每个块区域的开始之前和结束之后都总是有一个换行符。块区域不能用坐标来精确定位,而是顺序地置于包含它的区域内。当在某个块区域之前或内部加入和删除其他块区域时,此块区域的位置发生移动,以便腾出空间。块区域可能含有行区域、显示空格以及连续地排列在用来包含的块区域中的其他块区域。块区域还可能包含一个图形影像。产生块区域的格式化对象包括block、display-graphic、display-link、display-rule和list-block。
* 行区域表示块部分的一行文本。例如,列表项中的每个分开的行都是行区域。行区域可以包含内联区域和内联空间。对应的行区域没有格式化对象。取而代之的是,格式化引擎可计算行区域,例如确定在块区域内部如何折行。
* 内联区域是一行中的成分,如单字符、脚注引用或数学方程。内联区域可以包含其他内联区域和内联空间。产生内联的格式化对象包括character、inline-graphic、inline-link、inline-rule、inline-sequence和page-number。
15.2.1 fo命名域
在XSL样式单中,用于XSL格式化对象的XML元素放http://www.w3.org/XSL/Format /1.0命名域中,如下的声明所示:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/TR/WD-xsl"
xmlns:fo="http://www.w3.org/XSL/Format/1.0"
result-ns="fo">
选择fo作为前缀的概率大约为99%。因此,几乎总可以看到下列元素以fo作前缀:
* fo:bidi-override
* fo:block
* fo:character
* fo:display-graphic
* fo:display-included-container
* fo:display-rule
* fo:display-sequence
* fo:first-line-marker
* fo:float
* fo:flow
* fo:footnote
* fo:footnote-citation
* fo:inline-graphic
* fo:inline-included-container
* fo:inline-rule
* fo:inline-sequence
* fo:layout-master-set
* fo:list-block
* fo:list-item
* fo:list-item-body
* fo:list-item-label
* fo:multi-case
* fo:multi-properties
* fo:multi-property-set
* fo:multi-switc
* fo:multi-toggle
* fo:page-number
* fo:page-number-citation
* fo:page-sequence
* fo:region-after
* fo:region-before
* fo:region-body
* fo:region-end
* fo:region-start
* fo:root
* fo:sequence-specification
* fo:sequence-specifier-alternating
* fo:sequence-specifier-repeating
* fo:sequence-specifier-single
* fo:simple-link
* fo:simple-page-master
* fo:static-content
* fo:table
* fo:table-and-caption
* fo:table-body
* fo:table-caption
本章,我将使用fo作前缀,不再进一步说明。
命名域在第18章"命名域"中讨论。在那之前,??私獾闹皇荴SL格式化对象元素的名称都是以fo:开头。
15.2.2 格式化属性
总的来说,XSL文档中的各种格式化对象都指定内容放在页面中的顺序。但是,格式化的所有详细内容(包括页的大小、元素大小、字体、颜色等等,但不局限于这些)都是由XSL属性指定的。这些格式化属性以各自格式化对象元素的特性来表示。
这些属性中的许多属性的细节都应该从CSS中了解了。下面所进行的工作是为了确保CSS和XSL使用相同的名称来表示同一个内容。例如,CSS属性的font-family的含义与XSL的font-family属性是一回事;尽管在CSS和XSL中给属性赋值的句法不同,但值本身的句法是完全一样的。要说明fo:block元素格式化成与某种Times字体的近似,可以使用下面的CSS规则:
fo:block {font-family: New York, Times New Roman, Times, serif }
而XSL的等价语句可按下列方式,将font-family包括在fo:block开始标记中:
<fo:block
font-family="New York,Times New Roman,Times,serif">
尽管从表面上来看不同,但样式名(font-family)和样式值(New York, Times New Roman, Times, serif)却是完全一样的。CSS的font-family属性指定为一组字体名,各字体名以逗号分开,而顺序是从第一选择到最后选择。XSL的font-family属性指定为一组字体名,各字体名以逗号分开,选择顺序是从第一个选择到最后一个选择。CSS和XSL都将关键字serif理解为任意的衬线字体。
由于本章是基于XSL草案规范的第四稿,所以无法彻底完成CSS和XSL等效属性的完全同步。在下一个草案中将解决此问题。
当然,XSL格式化对象支持许多CSS中没有等效属性的属性,例如,font-size-adjust、ligature、character和hyphenation-keep。所以,需要学习这些属性,以便最大限度地发挥XSL的优势。标准的XSL属性有:
* auto-restore
* azimuth
* background
* background-attachment
* background-color
* background-image
* background-position
* background-repeat
* border
* border-after-color
* border-after-style
* border-after-width
* border-before-color
* border-before-style
* border-before-width
* border-bottom
* border-bottom-color
* border-bottom-style
* border-bottom-width
* border-collapse
* border-color
* border-end-color
* border-end-style
* border-end-width
* border-left
* border-left-color
* border-left-style
* border-left-width
* border-right
* border-right-color
* border-right-style
* border-right-width
* border-spacing
* border-start-color
* border-start-style
* border-start-width
* border-style
* border-top
* border-top-color
* border-top-style
* border-top-width
* border-width
* bottom
* break-after
* break-before
* caption-side
* cell-height
* character
* clear
* clip
* color
* column-count
* column-gap
* column-number
* column-width
* country
* cue
* cue-after
* cue-before
* digit-group-sep
* elevation
* empty-cells
* end-indent
* ends-row
* extent
* external-destination
* float
* flow-name
* font
* font-family
* font-height-override-after
* font-height-override-before
* font-size
* font-size-adjust
* font-stretch
* font-style
* font-variant
* font-weight
* format
* height
* href
* hyphenate
* hyphenation-char
* hyphenation-keep
* hyphenation-ladder-count
* hyphenation-push-char-count
* hyphenation-remain-char-count
* id
* indicate-destination
* inhibit-line-breaks
* initial
* initial-page-number
* internal-destination
* keep-with-next
* keep-with-previous
* language
* last-line-end-indent
* left
* length
* letter-spacing
* letter-value
* line-height
* line-height-shift-adjustment
* line-stacking-strategy
* margin
* margin-bottom
* margin-left
* margin-right
* margin-top
* max-height
* max-width
* may-break-after-row
* may-break-before-row
* min-height
* min-width
* name
* n-columns-repeated
* n-columns-spanned
* n-digits-per-group
* n-rows-spanned
* orphans
* overflow
* padding
* padding-after
* padding-before
* padding-bottom
* padding-end
* padding-left
* padding-right
* padding-start
* padding-top
* page-break-inside
* page-height
* page-master-blank-even
* page-master-even
* page-master-first
* page-master-last-even
* page-master-last-odd
* page-master-name
* page-master-odd
* page-master-repeating
* page-width
* pause
* pause-after
* pause-before
* pitch
* pitch-range
* play-during
* position
* precedence
* provisional-distance-between-starts
* provisional-label-separation
* reference-orientation
* ref-id
* richness
* right
* row-height
* rule-orientation
* rule-style
* rule-thickness
* scale
* score-spaces
* script
* sequence-src
* show-destination
* size
* space-above-destination-block
* space-above-destination-start
* space-after
* space-before
* space-between-list-rows
* space-end
* space-start
* span
* speak
* speak-header
* speak-numeral
* speak-punctuation
* speech-rate
* start-indent
* starts-row
* state
* stress
* switch-to
* table-height
* table-layout
* table-omit-middle-footer
* table-omit-middle-header
* table-width
* text-align
* text-align-last
* text-decoration
* text-indent
* text-shadow
* text-transform
* title
* top
* vertical-align
* visibility
* voice-family
* volume
* white-space-treatment
* widows
* width
* word-spacing
* wrap-option
* writing-mode
* z-index
15.2.3 转换成格式化对象
XSL格式化对象是用于在页面上排列元素的一个完整的XML符号集。使用XSL格式化对象的文档只是使用此符号集的结构整洁的XML文档。这意味着它有XML声明、根元素、子元素等等。它必须遵从任何XML文档的所有结构整洁的规则,否则格式化程序就不接受它。出于习惯,含有XSL格式化对象的文件要有.fob这三个字符作后缀。但是,由于它还是一个结构整洁的XML文件,所以很可能以.xml作后缀。
清单15-1为一用XSL格式化对象来标记的简单文档。文档的根元素为fo:root。此元素含有一个fo:layout-master-set和一个fo:page-sequence。fo:layout-master-set元素包含fo:simple-page-master子元素。每个fo:simple-page-master描述了用来放置内容的一类页面。其中只有一页非常简单的页面,但更复杂的文档可以有不同的主控页,用于第一页、右页、左页、正文页、封面内容、封底内容等等;每个文档又可能有一系列不同的页边距、页号以及其他特征。
使用fo:page-sequence可将内容放在主控页的许多副本上。fo:page-sequence包含fo:sequence-specification,指定不同的主控页应使用的顺序。其次,它还含有fo:flow子元素,此子元素保留以指定的序列放置在主控页上的实际内容。这里的内容是以两个fo:block子元素给出,而每个子元素的font-size属性值为20磅,font-family属性值为serif。
清单15-1:使用XSL格式化对象符号集的简单文档
<fo:root xmlns:fo="http://www.w3.org/XSL/Format/1.0">
<fo:layout-master-set>
<fo:simple-page-master page-master-name="only">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout master-set>
<fo:page-sequence>
<fo:sequence-specification>
<fo:sequence-specifier-single page-master-name="only"/>
</fo:sequence-specification>
<fo:flow>
<fo:block font-size="20pt" font-family="serif">
Hydrogen
</fo:block>
<fo:block font-size="20pt" font-family="serif">
Helium
</fo:block>
</fo:flow>
</fo:page sequence>
</fo: root>
尽管也许会像清单15-1中那样使用手工来编写文档,但这会失去XML所获得的内容格式独立性的所有优点。通常,应该编写XSL样式单,以便使用XSL转换符号集将源文档转换成格式化对象的符号集。使用清单15-2的XSL样式单,可将前一章中的清单14-1转换为清单15-1。
清单15-2:从源符号集到XSL格式化对象的变换
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns:fo="http://www.w3.org/XSL/Format/1.0"
result-ns="fo" indent-result="yes">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/XSL/Format/1.0">
<fo:layout-master-set>
<fo:simple-page-master page-master-name="only">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence>
<fo:sequence-specification>
<fo:sequence-specifier-single
page-master name="only"/>
</fo:sequence-specification>
<fo:flow>
<xsl:apply-templates select="//ATOM"/>
</fo: flow>
</fo:page-sequence>
</fo :root>
</xsl:template>
<xsl:template match="ATOM">
<fo:block font-size="20pt" font-family="serif">
<xsl:value-of select="NAME"/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
15.2.4 使用FOP
在撰写本书时,没有任何浏览器能够直接显示转换成XSL格式化对象的XML。只有一个软件可以使用以XSL格式化对象标记的文件,此软件即为James Tauber的FOP。FOP为免费的Java程序,它将FO(格式化对象,formatting object)文档转换成Adobe Acrobat PDF文件。可从http://www.jtauber.com/fop/站点下载最新版的FOP。
在撰写本书时,现有的FOP版本为0.6.0,它不完全支持格式化对象的子集和XSL第四草案中的属性。FOP是一Java程序,它可运行于适当兼容Java 1.1虚拟机的任何平台。要安装此程序,只需将fop.jar压缩文件放在CLASSPATH路径指明的目录中。com.jtauber.fop.FOP类包含用于本程序的main()方法。在命令行中,可使用指定输入和输出文件的参数来运行本程序。例如:
C:\XML\BIBLE\15>java com.jtauber.fop.FOP 15-1.fob 15-1.pdf
James Tauber s FOP 0.6.0
auto page-height: using 11in
auto page-width: using 8in
successfully read and parsed 15-1.fob
laying out page 1... done page 1.
successfully wrote 15-1.pdf
其中15-1.fob是输入的XML文件,它使用格式化对象符号集。15-1.pdf是输出的PDF文件,它能够在Adobe Acrobat或其他读取PDF文件的程序中显示和打印。
尽管PDF文件本身是ASCII文本,但本书不是有关PostScript的书籍,所以虽然精确地显示了上面的命令,读者却什么也得不到。如果好奇,可在任何文本编辑器程序中打开PDF文件。图15-1展示的转换文件,是使用Acrobat插件程序(plug-in),在Netscape Navigator中显示的。
图15-1 在Netscape Navigator中显示的PDF文件
对于使用XSL格式化对象来设置样式的XML文档来说,PDF文件不是唯一的或是主要的最终目标格式。当然,人们希望在不太遥远的将来Web浏览器能直接支持XSL格式化对象。就目前而言,PDF文件是唯一可用的格式,这也正是我要在本章中说明的内容。最终,应该有更多的软件能够阅读和显示这些文件。
15.3 页面布局
格式化对象的根元素是fo:root。此元素包含一个fo:layout-master-set元素和零或多个fo:page-sequence元素。fo:root元素通常有xmlns:fo特性,其特性值为http: //www.w3.org /XSL /Format /1.0,并且可能(尽管通常情况下没有)有一个id特性。fo:root元素的存在只为了声明命名域和文档根元素,它对页面布局或格式化没有直接的影响。
15.3.1 主控页面
fo:layout-master-set元素为一容器,用于文档使用的所有不同的主控页面。简单的页面控制与Quark XPress主控页面或PowerPoint幻灯母板的用途类似。每个都定义页面(包括此页的页边距、页眉大小、页脚、文本区域等等)的通用布局。在显示文档中的每个实际页面都基于主控页,以及从此主控页面中继承某些属性,如页边距、页编号和布局。
15.3.1.1 简单的页面控制
每个主控页面都是由fo:simple-page-master元素表示的。fo:layout-master-set可以包含一个或多个主控页面。一个fo:simple-page-master元素定义页的布局,包括页前区、主体区、后区、结束区以及开始区的大小。图15-2显示这些部分的典型布局。正文是中间留下来的所有内容。
图15-2 一页简单的英语文本各部分的布局
在正常的英语文本中,结束区处于页的右侧,开始区处于页的左侧。而在希伯来语或阿拉伯语的文本中,则反过来,因为这些语言是从右往左阅读。在几乎所有的现代语言中,前区是页眉,后区则是页脚,但在以从底部往顶部书写的语言中,这种情况则相反。
设计者利用适当的区域子元素可设置正文(中间部分)区、页眉、页脚、结束区和开始区的大小以及它们之间的距离。下面就是这些区域子元素:
* fo:region-before
* fo:region-after
* fo:region-body
* fo:region-start
* fo:region-end
这五个简单页面控制中的每一个区域都可以用fo:flow或fo:static-content元素来填充。
simple-page-master元素通常有三个主要特性:
1.page-master-name:这一页面控制的名称,页序列使用此名来选择依赖于特定页的主控页
2.page-height:页的高度
3.page-width:页的宽度
page-height和page-width可归入一个缩略属性size中。如果不提供这两个特性,那么格式化部分根据所使用的媒体(例如11"′ 8.5")来选择合理的缺省值。
例如,此处的fo:layout-master-set,含有两个fo:simple-page-master元素:一个用于偶数(左)页,一个用于奇数(右)页。它们两个都指定11英寸长,8.5英寸宽的页面大小。它们的顶和底页边距为0.5英寸。按照通常页面相对的情况,每个元素的的内侧页边距为0.5英寸,外侧页边距为1英寸,
<fo:layout-master-set>
<fo:simple-page-master page-master-name="even"
height="8.5in" width="11in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="l.0in" margin-right="0.5in">
<fo:region-body/>
</fo:simple-page-master>
<fo:simple-page-master page-master-name="odd"
height="8.5in" width="11in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="1.0in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
通常用于页面控制的其他特性包括:
* 影响页面边距的特性:margin-bottom、margin-left、margin-right、margin-top、margin
* 影响页面书写方向的特性:writing-mode、reference-orientation
15.3.1.2 区域属性
五个区域(before、after、body、start、end)共享相同的基本属性。这些属性有:
* 确定超出区域边界的内容如何处理的特性:clip、over-flow
* 确定内容在栏中如何折行的特性:column-count(区域中的栏号)以及column-gap(栏之间的距离)
* 影响区域背景的特性:background、background-attachment、background-color、background-image、background-repeat、background-position
* 影响区域边界的特性:border-before-color、border-before-style、border-before-width、border-after-color、border-after-style、border-after-width、border-start-color、border-start-style、border-start-width、border-end-color、border-end-style、border-end-width、border-top-color、border-top-style、border-top-width、border-bottom- color、border-bottom-style、border-bottom-width、border-left-color、border-left-style、border-left-width、border-right-color、border-right-style、border-right-width、border、border-top、border-bottom、border-left、border-right、border-color、border-style、border- width
* 影响区域贴边的特性:padding-bottom、padding-left、padding-right、padding-top、padding-bottom、padding-start、padding-end、padding-before、padding-after、padding
* 影响区域页边距的特性:margin-bottom、margin-left、margin-right、margin-top、margin、space-before、space-after、start-indent、end indent
* 影响区域中的书写方向的特性:writing-mode、reference-orientation
大多数属性与CSS属性同名,从CSS属性中就已很熟悉了。如果不明确地设置这些属性值,则选择合理的缺省值。对它们进行调整,就可以对页面的整个布局施加影响。
此外,四个外面区域(前、后、开始以及结束但不是正文)都有一个extent属性,它用来确定区域的大小。在去掉这四个区域之后,中间剩下来部分,就是主体正文的大小。
例如,下面的fo:layout-master-set使所有的外面区域都为1英寸。每个区域都有两个像素的黑色边界。而且,此页在所有的侧面上都有0.5英寸的页边距。
<fo:layout-master-set>
<fo:simple-page-master page-master-name="only"
height="8.5in" width="11in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="l.0in" margin-right="0.5in">
<fo:region-start extent="l.0in"
border-color="black" border-width="2px"/>
<fo:region-before extent="l.0in"
border-color="black" border-width="2px"/>
<fo:region-body
border-color="black" border-width="2px"/>
<fo:region-end extent="1.0in"
border-color="black" border-width="2px"/>
<fo:region-after extent="l.0in"
border-color="black" border-width="2px"/>
</fo:simple-page-master>
</fo:layout-master-set>
基于页面控制的正文页为5.5英寸宽,8英寸高。此值可以通过此页的大小减去此页上剩下来的其他部分的大小计算获得。
15.3.2 页序列
除fo:layout-master-set外,每个格式化对象文档通常还包含一个或多个fo:page-sequence元素。每个页序列按下列顺序含有三项内容:
* 一个fo:sequences-pecification元素,以定义主控页使用顺序
* 零个或多个fo:static-content元素,其中包含每页上要放置的文本
* 一个fo:flow元素,其中包含要在各页上依次放置的数据
fo:flow和fo:static-content之间的主要区别是,文本流(flow)中的文本并不放在多个页面上,但静态内容则是如此。例如,读者现在在阅读的这些行是文本流内容,只出现在此页上,而此页顶上的部分和章节标题则是静态内容,它在每页都是重复的。
fo:sequence-specification为此序列提供一组主控页。序列中的每页都有相关的页面控制,以定义页面的外观。清单15-1只使用一个主控页,但通常有多个主控页;例如,用于一章的第一页的主控页,用于所有的连续的左手页的主控页以及用于所有的连续的右手页的主控页。例如,可能有一个简单的页面控制用于目录,另一个用于正文文本,第三个用于索引。在这种情况下,目录、正文文本以及索引每个都对应有一个页面序列。
fo:flow元素按顺序包含本页上要放置的元素。当各页都以文本流的元素填充时,就会使用序列规格中的下一个控制布局方式为文本流中存在的元素创建新页。
fo:static-content元素包含每页上要放置的信息。例如,可将书的标题放在每页的页眉中。静态内容可以根据主控页来调节。例如,部分的标题可能放在左手的页上,章节的标题放在右手页上。还可以将fo:static-content元素用于像页码这样的项目,页码必须从一页到另一页不断地重复进行计算。换句话说,静态的实质并不是文本,而是产生文本的运算。
15.3.2.1 序列规格
使用铝腥?鲎釉?刂械囊桓龌蚨喔觯琭o:sequence-specification元素可列出特定的主控页被说明的顺序:
* fo:sequence-specifier-single
* fo:sequence-specifier-alternating
* fo:sequence-specifier-repeating
每个子元素都有特性,此特性确定何时使用哪个主控页。最简单的是fo:sequence-specifier-single,其page-master-name特性标识准备说明的主控页。例如,下面的fo:sequence-specification元素说明所有的内容都必须放在名为letter的主控页的一个实例上。
<fo:sequence-specification>
<fo:sequence-specifier-single page-master-name="letter"/>
</fo:sequence-specification>
如果有更多的内容可以填充在一页上,那么,超过的内容要么切去顶端,要么上卷,这要根据放置此内容各区域的clip和overflow特性值而定。但是,创建页数不会多于一页。现在来考虑一下下面的序列规格:
<fo:sequence-specification>
<fo:sequence-specifier-single page-master-name="letter"/>
<fo:sequence-specifier-single page-master-name="letter"/>
</fo:sequence-specification>
此段代码为每个基于letter页面控制的所有页都提供了序列规格。如果第一页填满,就创建第二页。如果那页填满,那么内容就被切去或上卷。
同样可将这一技术用来施加不同的主控页。例如,下面的序列规格将第一页以名为letterl的主控页为基础,第二页以名为letter2的主控页为基础。
<fo:sequence-specification>
<fo:sequence-specifier-single page-master-name="letterl"/>
<fo:sequence-specifier-single page-master-name="letter2"/>
</fo:sequence-specification>
当然,大多数时候不会预先精确地知道有多少页。fo:sequence-specifier-alternating和fo:sequence-specifier-repeating元素可用来指定按实际需要的页数来保存内容。fo:sequence-specifier-repeating元素为第一页指定一个主控页,为所有的后续页指定第二个主控页。fo:sequence-specifier-alternating元素为第一页、有内容的偶数页、有内容的奇数页、空白偶数页、最后的偶数页以及最后的奇数页指定多达六个不同的主控页。
例如,下面的序列说明符表示第一页的输出应使用名为letter_first的主控页,但所有的后续页都使用名为letter的主控页:
<fo:sequence-specification>
<fo:sequence-specifier-repeating
page-master-first="letter_first"
page-master-repeating="letter"
/>
</fo:sequence-specification>
如果整个内容都超出第一页,那么它就放在第二页上。如果超出第二页,那么就创建第三页。按照需要保存所有内容来建立页数。
在撰写本书时,仍未确定内容是否需要page-master-first和page-master-repeating。但如果只有单一主控页,肯定要像下面这样将其作为值重新用于page-master-first和page-master-repeating:
<fo:sequence-specification>
<fo:sequence-specifier-repeating
page-master-first="letter"
page-master repeating="letter"
/>
</fo:sequence-specification>
fo:sequence-specifier-alternating元素多用于打印书籍的章节,习惯上书籍的第一和最后一页,以及奇偶页上的页边距、页眉和页脚都不同。这个元素的特性可用来为这些所有不同页指定主控页。例如:
<fo:sequence-specification>
<fo:sequence-specifier-repeating
page-master-first="chapter_first"
page-master-even="chapter_even"
page-master-blank-even="chapter_blank"
page-master-odd="chapter_odd"
page-master-last-even="chapter_last_even"
page-master-last-odd="chapter_last_odd"
page-Master-repeating="letter"
/>
</fo:sequence-specification>
如果上面的特性似乎不对称的话