XSL-FO

XSL-FO是XSL Formatting Objects的縮寫，它是一種用於文檔格式的XML 置標語言。XSL-FO是XSL的一部分，而XSL是一組定義XML數據轉換與格式的W3C技術。XSL的其他部分有XSLT與XPath。截止到2006年12月12日，XSL-FO的最新版本是v1.1。

XSL-FO基礎

與其他的HTML與CSS組合不同，XSL-FO是一種unified表示語言，它沒有HTML中那樣的置標語法格式，並且與CSS更改外部XML或者HMTL文檔的預設表示不同，XSL-FO將所有的文檔數據保存在內部。
XSL-FO總的設計思想用戶寫到文檔中的數據是XML語言的文檔，而不是FO，所用語言可以是XHTML、DocBook以及TEI或者其他任何的XML語言。然後，用戶自己寫一個或者找一個XSLT變換，將XML轉換成XSL-FO。
一旦生成了XSL-FO文檔，就將它送到FO處理器這樣的應用程式中。FO處理器將XSL-FO文檔轉換成可以閱讀或者可以列印的格式。最常見的XSL-FO輸出格式是PDF或者PostScript，有一些FO處理器只能輸出成RTF這樣的格式或者只能輸出到圖形用戶界面的頁面序列及內容。
人們最初認為XSLT語言本身僅僅是為這個目的所用的，但是現在由於更加通用的XML轉換的出現已經超出了這個範圍。由於這個轉換是一個必然的過程，因此人們也常常將XML轉換為XSL-FO的XSLT當作XSL-FO文檔本身。甚至是XSL-FO的教程也在FO處理用法也用XSLT命令表示。
XSLT轉換過程功能非常強大，它可以自動生成內容的列表、參考連結、索引以及其他的結果。
XSL-FO文檔與PDF或者PostScript文檔不同，它沒有充分地描述文本在不同頁面上的布局，相反，它僅僅描述了頁面外觀以及不同內容放置的位置。根據這些，FO處理器依據FO文檔中描述的邊界確定文本的位置。XSL-FO規範甚至允許不同的FO處理器根據所生成的頁面有不同的響應。
例如，有些FO處理器為了節約空間在換行的時候會加入連字符，有些卻不會這樣做。不同的處理器甚至會使用不同的連字符算法，從一些簡單的算法到需要考慮前後行是否也許要連字符這樣複雜的算法。這樣就會在不同的頁面改變頁面布局，尤其是帶有邊框的時候更是這樣。另外還有一些場合，XSL-FO規範明確允許FO處理器根據布局作出一定的選擇。
雖然不同的FO處理器生成的結果並不一致，但是人們並不太關心。這是因為XSL-FO的目的是生成經過分頁的可列印媒體。XSL-FO文檔本身通常用於中介的媒體，通常用於生成PDF文件或者作為最終要分發的列印文檔。這與HTML直接作為最終形式分發給用戶有所不同。因此，如果需要生成一個列印文檔，只需要選擇滿足需要的FO處理器，比如布局效果以及較少的空白等，而無需在不同的處理器上測試XSL-FO文檔。

XSL-FO語言的概念

XSL-FO語言的設計目的是用於分頁媒體，採用的方式是類似於用於非分頁媒體的HTML以及CSS。因此，頁面是XSL-FO結構內在的一個概念，FO賦予了用戶很大的權利以確定如何在頁面上顯示信息。
FO最適合用在「內容驅動」設計的場合，這是圖書、文章、法律文檔等排版所用的標準方法。這涉及到一行鄰近的文本以及嵌入在頁面邊界中的不同變化信息。這與報紙與雜誌中所用的「布局驅動」設計有所不同。在那些文檔中，如果無法在特定的位置完整地放進去，那麼就會對內容進行裁減。XLS-FO很難處理雜誌布局的嚴格要求，實際上在很多場合，它根本不具備表示所需布局的能力。
儘管這種語言有這些設計局限，但是它仍然能夠勝任很多的表現任務。它提供表格、列表、side floats等許多特性。這些特性與CSS的布局特性類似，但是其中一些特性需要用XSLT表示。

XSL-FO文檔結構

XSL-FO文檔是XML文檔，但是不必遵循DTD或其模型規範。相反，它們遵循XSL-FO規範中定義的語法。
XSL-FO文檔包括兩個必須部分。第一部分列出頁面布局的細節，第二部分是帶有置標的文檔數據，根據不同的頁面布局確定如何在不同的頁面上擺放內容。
頁面布局定義了頁面的屬性。可以定義文本的排列方向以滿足不同語言的要求，定義頁面的尺寸以及頁面邊界。更加重要的特點是，它可以定義頁面的順序從而允許偶數頁與奇數頁的布局不同。例如，用於列印的文檔可以定義更大的邊界；在需要裝訂的時候可以留出更大的邊界。
文檔數據部分是一系列的數據流組成的，每個數據流都附屬於一個頁面布局。數據流包括一系列的按順序排列的數據塊，每個部分一系列的文本數據、內嵌的置標元素或者是二者的組合。在文檔邊界上也可以加入頁碼、章節等類似內容。
數據塊以及內嵌元素的功能非常類似於CSS，但是空白的填補與保留在FO與CSS之間有所不同。相對於頁面方向的數據塊及內嵌元素排列方向可以進行充分的定義，這樣FO文檔可以處理與英文排列方向不同的其他語言。FO規範的語言與CSS 2.1不同，使用開始與結束這樣的呈方向中性的術語而不是左與右來表示方向。
XSL-FO的基本內容置標是從CSS及其層疊規則派生出來的，因此XSL-FO中的許多屬性除非進行了顯示重載否則就會延伸到子元素的部分。

XSL-FO v1.0的功能

XSL-FO有許多處理文本布局的功能。除了上面介紹的一些之外，XSL-FO語言可以完成下面定義的功能。

多欄

一個頁面可能需要多欄的布局，在這種情況下，數據塊按照順序從一欄排到下一欄。單個的數據塊可以擴展到所有欄，在頁面中生成文本的分隔。分隔符上面的數據連在一起，下面的也連在一起，但是上面的不能與下面的連在一起。
根據XSL-FO頁面規範的特性，每個頁面可能會有不同的分欄及欄寬，因此文本可以很容易地從每頁3欄轉到每頁5欄或者每頁1欄。
FO的所有特性都能在多欄頁面的約束下正常工作。

列表

XSL-FO列表本質上就是兩列並排排列的數據塊。每個條目都由左側或者一行開始方向的數據與右側或者一行結束方向的數據塊組成。從概念上來說左側就是列表的編號或者標誌。但是，也可以是術語表中列出的簡單的字符串或者文本。右側的數據就是所要的結果。這兩塊數據都可以在同一個數據列表條目中包含多個數據塊。
通常XSL-FO列表的編號是XSLT或者其他生成XSL-FO文檔的過程產生的。因此，編號列表通常在XSL-FO顯式地進行編號。

腳註

用戶可以在頁面的底部創建腳註。在FO文檔中，腳註就像其他文字一樣，寫在他被引用的地方，FO處理器會把它當作一個或多個文字塊放在頁面的底部。FO處理器保證，不論被引用的是什麼，腳註都會和被引用的內容處在同一頁中。只有在極個別的情況下，這樣的處理會產生額外的空行。

表格

FO表格功能非常類似於HTML/CSS表格的功能。用戶定義每個單元格的行，用戶也可以定義每列的格式，如背景顏色等。另外，用戶也可以將第一行定義為表格標題，並且可以有自己的格式。
可以精確地告訴FO處理器每列的寬度，也可以讓用自動寬度匹配的方法分配寬度。

文本方向控制

FO有強大的文本方向控制能力。在一頁中間可以設定另外一種不同的文本板塊方向。這種文本板塊的方向控制可以用於不同語言的方向，或者是僅僅用於排版目的。實際上這些板塊可以包含從表格、列表、甚至是另外一個重新排列方向的文本板塊等在內的所有數據塊。

XSL-FO v1.1的功能

與1.0版相比，XSL-FO 1.1版加入了許多新的功能。

多數據流及數據流映射

XSL-FO 1.0對於一頁中文本的排列位置的要求相當嚴格，而1.1版大幅度地放寬了這些限制，允許文本數據流能夠映射到一頁中多個區域。這樣就可以象報紙那樣進行排版。

書籤

許多用於XSL-FO處理器的輸出格式，尤其是PDF格式都帶有書籤特性。這樣就可以在一個獨立的窗口中定義特定的字符串讓用戶選擇。當用戶選擇之後，文檔窗口就會立刻自動滾動到文檔中的特定區域。
現在XSL-FO v1.1中增加了添加書籤的能力，這樣處理器就可以將書籤傳遞給支持這種功能的格式。

索引

XSL-FO 1.1支持生成某些圖書後面具有的索引功能，這是通過對FO文檔中進行正確標記的元素進行索引所完成的。

XSL-FO的優點

由於XSL-FO是一種XML語言，因此從任何的XML語言生成XSL-FO代碼僅僅需要XSLT變換以及XSLT處理器。人們可以很容易地創作一個TEI或者DocBook格式的文檔，然後將它轉換成HTML用於網絡瀏覽或者經過FO處理器轉換成PDF用於列印。實際上，現在已經有許多用於這些目的的TEI以及DocBook XSLT轉換工具。
另外，由於它是一種XML語言，尤其是由於它沒有固定的語法或者文件類型定義，它可以保存所有類型的XML數據。最常見的數據有SVG圖像，許多FO處理器都可以讀取或者將它加入到文檔中。
XSL-FO的另外一種優點是用法相當簡單。這種語言大多數的功能都是基於CSS的工作，因此CSS用戶對於那些基本的標記屬性相當熟悉。相對於難於理解的TeX這樣的布局與排版來說，FO文檔的特定部分將如何顯示也顯得很容易理解。

XSL-FO的缺點

FO的主要缺點是對於它的支持不多。FO很難、或許沒有一家能夠具有與規範100%的兼容性。儘管規範已經出現了很多年，但是現實仍然是這樣。通常這是由於缺少對於XSL-FO的需求而引起的。TeX及其他類似產品已經在排版語言市場上占據了很長時間，大多數TeX用戶都沒有切換到XSL-FO的需求。
XSL-FO另外一個不太嚴重的缺點是將數據排列到頁邊的功能不夠強大，控制類似數據的能力可能沒有用戶所想像的那樣。
FO的另外一個問題是，儘管容易理解，但是如果手工生成這樣的文檔非常困難，並且非常繁瑣。XSLT就是用來更加方便地生成XSL-FO文檔的，因此沒有使FO文檔更加簡練的推動力。這樣帶來的問題就是新手不僅要學習如何寫FO文檔的細節，而且要學習寫XSLT變換。當然，如果不是從一個現有的用於標準文檔格式的XSLT變換開始，這會變得很困難。