原始版本: http://www.w3.org/Style/styling-XML

翻譯: web practice

聲明:原始版本(英文版)是唯一的官方版本。中文(繁體)版本是根據W3C網站上的文件翻譯的,可能存在某些錯誤。翻譯不保證譯文完全準確。請您自己承擔風險。


如何給XML添加樣式

(This page uses CSS style sheets)

樣式

該選用哪一種?

外部

CSS

嵌入式

XSL

CSS2 推薦包含一個關於使用XML,CSS的簡短的教程(見§ 2.2)。當編寫CSS2的時候,官方的XML的樣式規範還沒有準備。這就是那個教程裡應該包含的內容。注意例子使用CSS,但是大多數情況下,那些樣式規則也能用XSL編寫。

外部樣式表

Tip: 請在你的瀏覽器裡試一試

HTML有一個link元素 來鏈接外部樣式表,但是並不是每個基於XML的格式都會有這樣一個元素。如果沒有適合的元素,你仍然可以通過附加外部樣式表xml-stylesheet處理指令的方法,如下:

<?xml-stylesheet href="my-style.css" type="text/css"?>
... rest of document here...

這個處理指令(PI)必須放在文檔第一個標籤的前面。type="text/css"不是必需的,但是這個能夠幫助瀏覽器:如果它不支持CSS,它就知道它不會需要下載此文件。

只要用HTML的link元素,就會有復合的xml-stylesheet處理指令,它們有設置類型、媒介和標題的屬性。

這裡有大量的例子。假設我們有三個樣式表,一個設置各個元素的基本顯示類型(內聯,段,列表條目等等)。還有兩個不同的,分別設置顏色和頁邊距。後面的兩個是二選一的,文檔的讀者可以選擇使用其中一個。除非要打印文檔,那樣我們就必須選擇最後那種。下面是普通樣式表:

/* common.css */
INSTRUMENT { display: inline }
ARTICLE, HEADLINE, AUTHOR, PARA { display: block }

這是替代樣式表之一,在文件裡稱為“modern.css”:

/* modern.css */
ARTICLE { font-family: sans-serif; background: white; color: black }
AUTHOR { margin: 1em; color: red }
HEADLINE { text-align: right; margin-bottom: 2em }
PARA { line-height: 1.5; margin-left: 15% }
INSTRUMENT { color: blue }

這還有另外一個,稱為“classic.css”:

/* classic.css */
ARTICLE { font-family: serif; background: white; color: #003 }
AUTHOR { font-size: large; margin: 1em 0 }
HEADLINE { font-size: x-large; margin-bottom: 1em }
PARA { text-indent: 1em; text-align: justify }
INSTRUMENT { font-style: italic }

有這三個樣式錶鍊接的XML文檔看起來是這樣的:

<?xml-stylesheet href="common.css" type="text/css"?>

<?xml-stylesheet href="modern.css" title="Modern" media="screen"
  type="text/css"?>
<?xml-stylesheet href="classic.css" alternate="yes"
  title="Classic" media="screen, print" type="text/css"?>
<ARTICLE>
  <HEADLINE>Fredrick the Great meets Bach</HEADLINE>
  <AUTHOR>Johann Nikolaus Forkel</AUTHOR>
  <PARA>
    One evening, just as he was getting his 
    <INSTRUMENT>flute</INSTRUMENT> ready and his
    musicians were assembled, an officer brought him a list of
    the strangers who had arrived.
  </PARA>
</ARTICLE>

有關更多的詳情,見W3C推薦“結合XML文檔樣式表”

嵌入式樣式表

Tip: 請在你的瀏覽器裡試一試

HTML有一個style元素,可以讓樣式表直接嵌入HTML文件裡,而不需要外部文件。在某些情況下這個更容易,尤其是當該文檔裡的樣式表非常特定的時候。

大多數基於XML的格式不會有這樣的一個元素,但是同樣的鏈接到外部樣式表的處理指令,也能用來指向在文檔本身嵌入的樣式表。 截止2006年2月,這個還是存在一個技術問題,也沒有正式的規範存在。 例如:

<?xml-stylesheet href="#style" type="text/css"?>
<ARTICLE>
  <EXTRAS id="style">
    INSTRUMENT { display: inline }
    ARTICLE, HEADLINE, AUTHOR, PARA { display: block }
    EXTRAS { display: none }
  </EXTRAS>
  <HEADLINE>Fredrick the Great meets Bach</HEADLINE>
  ...
</ARTICLE>

在這種情況下,type="text/css"屬性必須存在,否則瀏覽器(或是其它的應用程序)必須要猜測樣式表的語言。 xml-stylesheet處理指令現在沒有指向一個外部樣式表,但是指向了文檔本身的一個元素。那是一個由id屬性定義的元素,作為連接的標籤服務的。 (決定於特殊的XML格式,id屬性可能會被稱作其它的;在某些格式裡,可能會根本沒有一個適合的屬性。)

未解決的問題

W3C推薦“結合XML文檔樣式表”沒有定義嵌入式樣式表的情況,儘管看起來似乎是一個合理的推斷,讓URL片段(用一個“#”開始的)。這時,2006年初,仍然有沒解決問題,也沒有頒布規範。問題如下:

  1. 因為嵌入式樣式表不是從服務器上單獨下載的,服務器就不能告訴瀏覽器樣式表的格式是什麼。因此,在這種情況下就需要type屬性。不確定會怎樣,如果這個屬性缺失:樣式表被忽略?如果假設是CSS呢?是否有什麼算法可以確定這個語言呢?
  2. 大多數基於XML的格式,一個片段識別碼定義一個完整的元素,而不是一個元素的內容。但是一個用“ARTICLE”開始的樣式表不是正確的CSS,所以似乎需要額外的規則:一個樣式表處理指令裡使用的片段識別碼,指向一個元素的內容而不是元素本身。
  3. 類似的情況,如果指向的是元素裡的一個子元素,也不能確定會怎樣。是不是組成樣式列表的全部元素的所有內容都是串聯的?只是第一個元素的內容?或只是一個錯誤,還是整個元素都忽略了?
  4. 在上面的例子裡,URL指向文檔本身。事實是,瀏覽器能夠讀取在那個URL的所有指令,它知道如何分析XML,也有找到指令樣式元素的能力。但是現在想想指向一個外部文檔的某片段的一個URL。為了成功的回复樣式表,瀏覽器必須先下載在解析外部的文檔,然後提取和分析出樣式表。但是type屬性只給出了兩者之間一個的類型,所以瀏覽器不知道是否可以用這個樣式表。它沒有,甚至沒有定義type屬性給出的外部文檔類型或是嵌入在裡面的樣式表。
  5. 使用“Generic XML”,樣式表處理指令最有用,例如:在格式裡使用瀏覽器不知道的XML。多虧樣式表,至少還能顯示一些東西。有名的格式,如:SVG,SMIL或XHTML,雖然有它們自己的規則來轉換,但超過了一個樣式表能指定的。而當文檔當做Generic XML看待時,有些其它的東西瀏覽器還是不知道:特別是,它不知道那個屬性是ID屬性。有一個關於被稱作xml:id屬性的W3C推薦,若果文檔中有包含那個名字的屬性,很可能URL片段會指向這些的其中一個。但如果沒有這樣的屬性,瀏覽器一定會嘗試其它的方法來決定哪些屬性是IDs。如果文檔有一個DOCTYPE在頂部,瀏覽器就能回复它指向的DTD,DTD也會指定屬性。但是瀏覽器可能不能讀出DTDs或是沒有一個DOCTYPE。
  6. 在文檔裡,一個片段ID是唯一的指向一個元素的方法,另外一個W3C推薦定義了XPointers來辨別文檔裡的元素,而不用ID屬性。但是瀏覽器使用樣式表處理指令,目前還沒有要理解XPointers的這個要求,因此就不清楚是否瀏覽器需要解釋XPointers,是否它們能,還是它們必須忽略。

內聯定義

HTML也允許通過style屬性的方法,把樣式直接附加到單個元素。大多數基於XML的文檔格式沒有這樣的一個屬性,雖然有些允許讓來自HTML的功能()在文檔內使用。

類別屬性

Tip: 請在你的瀏覽器裡試一試

class屬性允許你創建HTML元素子類別,但不太可能在大多數基於XML文檔格式裡提供。當然,CSS讓你能夠在任何屬性的基礎上選擇元素,不僅僅是class,但是句法就沒有那麼方便。

這裡有一個例子。如果有一個class屬性,文檔格式定義它在HTML里工作,我們可以用點符號。 (因此,這個特殊的例子就不會工作了,因為<doc>不是像class那樣能夠讓瀏覽器知道的格式。)

<?xml-stylesheet href="#s1" type="text/css"?>
<doc>
  <s id="s1">
    s { display: none }
    p { display: block }
    p.note { color: red }
  </s>
  <p>Some text... </p>
  <p class="note">A note... </p>

</doc>

如果文檔格式沒有指定class創建一個子類別,接下來你必須要使用帶有“[ ]”的更長的選擇器:

<?xml-stylesheet href="#s1" type="text/css"?>
<doc>
  <s id="s1">
    s { display: none }
    p { display: block }
    p[class~=note] { color: red }
  </s>
  <p>Some text... </p>
  <p class="note">A note... </p>

</doc>

如果沒有class屬性,但是有其它我們可以使用的,屬性選擇器“[ ]”仍然適用:

請在你的瀏覽器試一試

<?xml-stylesheet href="#s1" type="text/css"?>
<doc>
  <s id="s1">
    s { display: none }
    p { display: block }
    p[warning="yes"] { color: red }
  </s>
  <p>Some text... </p>
  <p warning="yes">A note... </p>

</doc>
Bert Bos
Created 29 February 2000 (last update: $Date: 2009/12/15 20:59:04 $)