XML來自何處?
XML起源於SGML(Standard Generalized Markup Language。換句話說,你可以既使用XML也可以使用SGML來創建自己的描述性文檔。這兩種語言都使用文本標識(Tags)來描述數據以供其他應用或是工具(例如一個SGML或是XML分析程序)使用。有了XML,它們可以正確的讀取信息並對數據進行一些有趣的操作。XML是SGML的一個簡化版本,它更適合於在Web上使用。
XML的語法
XML定義了用來描述你的數據的語法。一下就是一句正確的XML語句:
<hamburger name="CowBurger" lowfat="dream on"/>
和其他的標識語言有所不同,XML對大小寫是敏感的。所以,<hamburger>元素和<Hamburger>元素在XML中是不同的。同時,XML不會忽略空格(其他的語言常常忽略空格)。對每一個可能對文檔結構造成混淆的字符,XML都會仔細的處理(就像< and >)。
如果一個XML文檔只含有一個根元素,並且所有的子元素都被正確地放在父元素中,這樣的XML具有良好的風格。更具體地說,就是對每一個給定的子元素,它的begin和end tag都只存在於相同的父元素中。下面就是一段風格良好的XML文檔示例(hamburger.XML)。
<?XML version="1.0"?>
<hamburgers>
<hamburger lowfat="dream on">
<name>CowBurger</name>
<description>Greasy and good.</description>
<price>2.99</price>
</hamburger>
</hamburgers>
誰來定義Tags?
讀了前面的部分後,你會發現你已基本上了解了XML的語法。其實這裡的內容並不是很多,XML確實是非常簡單。
可能你已經注意到了,XML看起來很像HTML(Hypertext Markup Language)。他們都用相同的語法來定義begin和end tag以及一些屬性。從本質上說,Html使用的是一些預先設定好的元素和方法,只是XML的一個特例。這些元素及其相關的方法決定了浏覽器如何解釋一個XML文檔,進而提供給最終用戶。
和Html為創建用戶界面提供了一種通用的方法一樣,XML提供了一種描述並協同數據工作的通用方法。XML允許開發者創建自己的XML詞匯,用自定義的方式描述他們自己的數據結構。假如一個開發者正在為一個快餐連鎖店開發軟件,那麼,為了描述一些食品,一個"漢堡包"元素可能會十分的方便。
一旦開發者使用了XML來描述他們的數據,他們就可以很方便的在相同的或是不同的系統中對這些數據進行互操作。當然,前提是那些系統都能理解XML。譬如說,一位開發者可以使用來自另一個系統的數據,只要那些數據是用XML描述的。如此一來,開發者在考慮軟件的互操作性時就再也不必擔心諸如平台、操作系統、語言、或是數據存儲等各方面的不同了。XML是實現系統之間互操作性的最簡單工具。
XML的名字空間
由於XML對互操作性的支持,每個人都可以創建屬於自己的XML詞匯。這樣一來,如果不同的開發者用相同的元素來代表不同的實體的話,後果是不可想象的。為了防止這種潛在的沖突,W3C在XML中引入了名字空間。
XML名字空間為你的XML文檔元素提供了一個上下文。它允許開發者按一定的語義來處理元素。還以漢堡包舉例說明,在某個系統中price元素可能代表的是消費者的購買價,而在另一個系統中,它可能代表了商店的進貨價。下面的例子演示了名字空間是怎樣幫我們解決這樣的問題的。
<?XML version="1.0"?>
<hamburgers
XMLns:purchase="http://fastfood.org/franchise/prices"
XMLns:sales="http://fastfood.org/customer/prices"
>
<hamburger lowfat="dream on">
<name>CowBurger</name>
<description>Greasy and good.</description>
<purchase:price>0.99</price>
<sales:price>2.99</price>
</hamburger>
</hamburgers>
我怎樣使用XML呢?
XML的語法並不難,但想要用好XML,讓它幫我們做一些事還是有一定的挑戰性的。
要用好XML,我們要能編程處理XML文件。W3C定義了一種軟件模型叫"XML處理器"。它能夠讀XML文檔並提供對其內容和結構的訪問。微軟最主要的XML處理器叫做Microsoft XML(MSXML) 2.0。MSXML 2.0 捆綁於IE 5.0中,並且可以作為一個單獨的可分發文件從微軟MSDN XML的網站免費獲得(http://msdn.microsoft.com/XML)。
使用XML來作為描述數據的通用標准的一個主要優點在於,任何XML處理器所提供的功能都能讓我們實現我們想到的目標。開發者幾乎不用(如果你曾這麼干過)費力去寫自己的XML處理器。理論上說,開發者應該使用市場上最好的處理器以避免出現兼容的問題。
使用一個標准的XML處理器,你可以通過編程讀各種XML文檔(例如hamburger.xml),訪問任何元素、元素內容或是元素屬性。如果你在一個基於Windows的系統中創建XML文檔,你也可以很方便的將這個文檔轉到大型機系統中,用大型機的XML處理器來實現與同樣數據的交互。這才是XML的真正魅力所在。作為一項技術,XML並不能解決你的軟件的所有問題;但它已成為一種在你和他人的應用之間交換結構化數據的開放式有效機制。
XML的核心技術
直到現在,你已經完全可以創建使用屬於你自己的XML文檔了。然而,XML真正的潛力卻在於它所支持的多項技術。你完全不必為此去使用本文以下所討論的所有技術。但它們的出現可以幫助你理解這些技術是怎樣作為整個XML策略的一部分被組合在一起的。
確認技術
你已經知道了XML為描述結構良好的文檔提供了一整套靈活的語法。正因為它的這種靈活性,我們需要一些方法來確認某一種特殊類別的XML文檔都有我們所預計一種格式。例如,以下就是一個結構良好的XML文檔:
<?XML version="1.0"?>
<hamburgers>
<hamburger lowfat="dream on">
<hamburger lowfat="maybe">
<name>CowBurger</name>
<description>Greasy and good.</description>
<price>2.99</price>
<price>3.99</price>
</hamburger>
</hamburger>
</hamburgers>
然而,這個文檔有一些應用級的問題。注意到了嗎,文檔中一個hamburger元素出現在了另一個hamburger元素的裡面。請別擔心,對於這個例子來說這個XML結構沒有任何的錯誤。另外,請注意在裡層的hamburger元素中有多個price元素。哪一個price是正確的呢?系統有可能會顯示出這裡有一個Bug。在這種情況下,一個標准的確認XML文檔的機制將是十分有用的。
schema
一個schema通常是一組為了描述一類給定的XML文檔而預先定好的規則。它定義了可以在指定XML文檔中出現的各個元素以及和某個元素相關的若干屬性。它同時定義了關於XML文檔的結構化信息,比如哪幾個元素是其他元素的子元素,子元素出現的順序和他們的數量。它還可以定義一個元素是否為空,能否包含文本或者屬性是否有默認值。
DTDs(Document Type Definitions)和XML數據 都是怎樣描述XML文檔計劃的具體例子。
文檔類型定義(Document Type Definitions)
DTD語言是為了定義SGML文檔的確認規則而專門開發的。因為XML是SGML的一個子集,所以DTDs也可以用來定義XML的確定規則。與XMLschema不同,一個XML處理器可以在運行時用DTD來確定一個XML的合法性。
DTD的語法有時可能會有一些晦澀難懂。DTDs使用不同的語法元素,諸如驚歎號、圓括號、星號、尖括號等,來定義在一個XML文檔中那些元素是必備的,哪些是可選的以及可以出現的元素數量等等。DTDs同時還定義了元素之間的關系和屬性於不同元素之間的關系。
下面就是前面列出的hamburger.XML的DTD(hamburger.dtd):
<!ELEMENT hamburgers (hamburger)*> <!ELEMENT hamburger (name, description, price)> <!ATTLIST hamburger lowfat CDATA #IMPLIED> <!ELEMENT name (#PCDATA)> <!ELEMENT description (#PCDATA)> <!ELEMENT price (#PCDATA)>
這篇文檔指出,hamburgers元素可以包含多個hamburger元素。同時,每一個hamburger元素必須包含一個lowfat屬性和三個子元素,所有的類型都是#PCData(parsed character data)。遵從這篇DTD的文檔都必須加入下面一行代碼:
<!DOCTYPE hamburgers SYSTEM "hamburger.dtd">
這句聲明告訴分析器不論DTD中的schema是什麼都認為XML文檔的內容是合法的
盡管MSXML 2.0支持DTDs,但是你還是會發現使用它們是很費力的。它非常復雜並且難於掌握與使用。請注意,DTD語法並不是合法的XML。正因為如此,XML的處理器除了XML語法,還要支持用來描述schema的DTD語法。設想一下,假如我們用XML來描述schema,那麼開發者,特別是XML工具的提供者,所承擔的XML文檔檢驗工作將會變得容易得多。W3C正在考慮幾種彌補DTDs不足的方案以提高現在的語法定義過程。
XML數據
XML-Data是一種XMLschema語言。在微軟的定義中,XML-Dataschema通常是指XMLschema,而不是DTDschema。一個XML-Dataschema是一個具有良好結構的XML文檔。XML-Data語言基於XML-Data DTD,後者指明所期望的schema定義格式。因為XML-Dataschema是簡單的XML文檔,任何用於XML文檔的工具都可以用來定義XML-Dataschema。
以下的XML-Dataschema產生的schema和先前由hamburger.dtd所定義的schema是一樣的:
<?XML version="1.0"?>
<Schema xmlns="schemas-microsoft-com:XML-data">
<ElementType name="name" />
<ElementType name="description" />
<ElementType name="price" />
<AttributeType name="lowfat" />
<ElementType name="hamburger" />
<element type="name" maxOccurs="1" />
<element type="description" maxOccurs="1" />
<element type="price" maxOccurs="1" />
<attribute type="lowfat" maxOccurs="1" />
</ElementType>
<ElementType name="hamburgers" model="closed">
<element type="hamburger" maxOccurs="*" />
</ElementType>
</Schema>
在XML-Dataschema中定義元素和屬性時,分別用到的是<ElementType>和<AttributeType>元素。它們提供了對元素和屬性類型的定義。定義一個元素或是屬性時用<element>或<attribute>標簽。你可以通過定義minOccurs/maxOccurs來指定元素允許出現的數量。schemaXML結構還定義了元素在XML文檔中允許出現的位置(例如一個<hamburgers>元素可以包含若干<hamburger>元素,等等)。
微軟通過MSXML 2.0對XML-Data提供支持。根據微軟的XML SDK文檔,捆綁在IE 5中的XMLschema的實現基本上依托於W3C於1998年1月發布的XML-Data Note。它提供了對XML-Data子集的支持,這雖然和XML的語法稍有不同,正好直接和DCD中闡明的功能相吻合。
處理器(API)技術
我們在前面已經提過了,為了有效的使用XML,你必須通過編程來訪問數據。我們將一個能訪問XML文檔同時又能提供對其內容和數據結構進行訪問的軟件模塊稱為一個XML處理器或是一個XML API。
雖然開發者完全有自由去開發或使用他們自己的XML API,但從他們的利益出發,我還是建議他們使用行業標准的API。因為只有接受了行業標准的API,開發者寫出的代碼可以無需修改便能在其他的環境中順利執行。
目前有兩種主要的API已經得到了廣大開發者的廣泛使用,即將成為未來的行業標准。它們分別是:DOM(Document Object Model)和SAX(Simple API for XML)。
DOM 文檔對象模型
文檔對象模型是一種通過編程方式對XML文檔中數據及結構進行訪問的標准。W3C已經同意將其列為未來行業標准第一等級規范的推薦對象。
DOM是基於XML文檔在內存中的樹狀結構。當一個XML文件被裝入到處理器中時,內存中建立起一棵相應的樹(見圖1)。DOM還定義了用來遍歷一棵XML樹和管理各個元素、值和屬性的編程接口(包括方法和屬性的名字)。
Figure 1. XML in-memory representation
MSXML 2.0完全支持DOM並提供了一個易用的對象模型與內存中樹進行交互。下面是一個簡單的VB例子,它演示了如何用MSXML來遍歷一顆樹的所有子元素。
Set xmlDoc = CreateObject("MSXML.DOMDocument")
bSUCcess = xmlDoc.load("hamburger.XML")
If bSuccess Then
For Each node in XMLDoc.documentElement.childNodes
val = node.text
Next
End If
SAX
DOM標准的一個主要不足在於將整個XML文檔裝入內存所引起的巨大開銷。當文件的數據量非常大時,這會給我們帶來一些問題。當你在內部網或是因特網上傳輸如此巨大的XML文件時,你可能等不及所有的文件傳輸結束就開始處理數據。很多XML的開發者已經意識到這一點,於是他們一起努力(從XML-DEV郵件列表開始)開始創立另一種新的標准。這就是SAX。雖然SAX還處於發展的初期,但因為它出色的性能,它正快速的得到大家的歡迎。
SAX是一種非常簡單的XML API(正如它的名字那樣,Simple API for XML),它允許開發者使用事件驅動的XML解析。與DOM不同,SAX並不要求將整個XML文件一起裝入內存。它的想法十分的簡單,一旦XML處理器完成對XML元素的操作,它就立刻調用一個你自定義一個事件處理器及時的處理這個元素和相關數據。這樣做雖然能極大的提高效率,但也會造成一定的問題。比如說,開發者將不得不在靈活性上受到限制。如果你想了解更為詳細的資料,請訪問http://www.megginson.com/SAX/sax.Html。
轉換技術
一旦你開始使用標准的DOM API來實現於XML數據的交互,你便會發現,無論是從一個大型的文檔中取得一個特定的數據,還是將一個XML文檔的某一部分轉換為另一種格式的數據(例如HTML),都是十分單調乏味的。
舉個例子說,假如你想找到所有的lowfat hamburger price元素。為了用標准的DOM API來完成這一切,你必須通過手工地書寫代碼遍歷整顆樹來找尋符合條件的元素(在本例中,條件是指在hanburger元素中lowfat=yes的price元素)。再看另一個例子,假設你想將所用的hamburger元素和相關的數據轉換為簡單的HTML表格以供用戶交互使用。使用標准的DOM API,你得手工遍歷整棵樹來獲得Html表格中所需的數據。
我為了標准化及簡化人們完成這些任務所需做的工作,W3C推薦使用XSL(Extensible Stylesheet Language)和一種叫做XSL Patterns的簡單查詢語言。
XSL Patterns
一個模式就是一個字符串,通過它來選取XML樹中的節點。這樣的選取取決於模式所關連的當前節點。元素的名字是最簡單的模式,這個模式選取了當前節點所有具有該名字的子節點。例如,hamburger模式選取了當前節點的所有hamburger子節點。
模式的語法非常完備。它允許你標識某個指定元素在文檔中所處的上下文(例如,price元素在hamburger元素之中),同時它還提供了強大的篩選句法,使得我們可以標識出符合給定條件的節點(例如,lowfat=yes)。為了找出一個hamburgers元素中的所有lowfat hamburger price元素,你可以使用以下的模式字符串:
/hamburgers/hamburger[@lowfat="yes"]/price
當某個模式被應用於給定的節點時,它僅返回符合指定模式的節點列表。這大大簡化了開發者的操作,不再需要遍歷整棵樹。
MSXML 2.0對模式語法的支持和Extensible Stylesheet Language (December 18th Working Draft)中2.6節的定義是相同的。MSXML 2.0中的IXMLDOMNode接口提供了兩個方法,SelectNodes和SelectSingleNode。這兩個方法都以一個模式串為參數。例如,下面的一行代碼將返回滿足條件的所有price節點。
Set nodeList = rootNode.selectNodes("hamburger[@lowfat="yes"]/price")
XSL
XSL模式可以幫助我們標識一篇給定XML文檔中的某些節點,但對這些節點的操作最終還是有賴於開發者來完成。XSL可以幫助我們簡化完成通常XML任務的過程:將XML節點從一種格式轉化到另一種格式。這種對格式轉化的需求起源於web開發者需要將他們的XML數據轉化為Html數據以供用戶浏覽。
實際上,XSL所能做得遠比以上描述多得多。XSL能夠有效的定義從一種XML格式到另一種XML格式之間的轉換,這極大的增強了互操作性。假如某個人向你的系統發送了一篇XML文檔,而你的系統不認識它所采用的XML詞匯,你只要進行一次簡單的XSL轉換就可以得到自己熟悉的詞匯。正是由於XML這種簡單的特點,開發者才不用為了描述某種類型的數據而采用通用的詞匯。
一個XSL文件中包含了一系列定義轉換規則的聲明模板。每一個模板都明確定義了怎樣將源文檔中的指定節點轉換為輸出文檔中的節點(或其它類型的數據)的方法。你可以使用XSL模式來決定一個模板應用於一篇文檔中的那些部分。
作為一個示例,下面轉換hamburger XML文件:
<?XML version="1.0"?>
<hamburgers>
<hamburger lowfat="dream on">
<name>CowBurger</name>
<description>Greasy and good.</description>
<price>2.99</price>
</hamburger>
</hamburgers>
轉換到Html文件:
<Html>
<body>
<h1>hamburgers</h1>
<ol>
<li>CowBurger, $2.99, Greasy and good.</li>
</ol>
</body>
</Html>
你使用的XSL文件如下:
<?XML version="1.0"?>
<xsl:stylesheet XMLns:xsl=" http://www.w3.org/TR/WD-xsl ">
<xsl:template match="/">
<Html>
<body>
<h1>hamburgers</h1>
<xsl:for-each select="hamburgers[@lowfat="dream on"]>
<li><xsl:value-of select="name"/>, <xsl:value-of select="price"/>,
<xsl:value-of select="description"/></li>
</xsl:for-each>
</body>
</Html>
</xsl:template>
</xsl:stylesheet>
注意到了嗎,我們是怎樣在不同XSL元素的match和select屬性中使用XSL模式來標識元素集的?在<xsl:template>標簽中定義了一組節點的轉換規則。XSL使用了一套標准的XML詞匯來定義轉換的過程,是不是很有趣呢?
鏈接技術
很多人都認為,Html真正強勁的地方在於它的錨元素。
<A HREF = "http://www.someserver.com">some link</A>
錨元素使開發者可以建立從一個Html頁面到另一個頁面的鏈接,定義兩個文檔之間的關系。這給用戶提供了一種從當前頁面中獲取更多相關數據的途徑。同時,這也是用戶在查詢數據中所使用的典型方法。為了查找數據,他們浏覽某一頁面,同時他們在這篇該頁面中可能會發現更符合他們要求的內容。而這些內容通過一個鏈接,存放在不同的頁面上。
整個Web就是基於這樣一個在不同的數據文件之間建立關系(鏈接)的基石上的。隨著IT行業不斷的向前發展,我們自然會想到用類似的機制來描述不同XML文檔或是相同文檔中不同元素之間的聯系。
XLink
XML Linking 1.0 (XLink)是W3C主導的定義XML鏈接的語法。根據XLink 1.0文檔的要求,一個XML鏈接,或XLink的描述信息,顯式的指定了資源或部分資源之間的關系。在XLink中,我們並不涉及標示不同類型數據位置的方法(例如URIs、XPointers和圖形坐標)。
這裡是一個XML連接的簡單例子:
<hamburger XML:link="simple" HREF =
"http://fastfood.org/hamburger.ASP">
</hamburger>
XPointer
在前面的章節中你已經讀到,XLink需要依靠不同的機制來標識你想要鏈接的資源(例如統一資源標識符)。W3C推出了另一種叫做XPointer的機制用於構造XML文檔的內部結構。具體地說,它決定了一篇XML文檔中的元素、字符串或其它部分是否具有某個具體的標識。
一個XPointer包括一系列描述位置的術語,它們中的任何一個都指定了一個特定的位置信息,通常這樣的位置信息總是和前一個術語所指定的位置信息相關聯。每一個位置術語都有一個關鍵字(例如id,child,ancestor等等)和若干變量,諸如實例的序列號、元素類型或屬性。看下面的例子:
child(2,hamburger)
指的是第二個類型為hamburger的元素。
其他XML相關的技術和詞匯
目前為止我們所談到的已經代表了XML的核心技術。可能你覺得這些東西已經足夠了,但如果我們不深入下去對眼下一些正流行起來的XML相關技術和詞匯作一些介紹的話,這篇文章探討XML的文章就顯得不是很完整了。目前,這些新技術正在W3C的開發小組的努力下一步步走向成熟。
MathML(Mathematical Markup Language)
MathML是一種用來描述數學符號、紀錄其結構和內容的XML應用。MathML的目標是在Web上實現能像Html處理文本一樣,處理數學問題。下面是由W3C提供的的MathML例子。數學方程:
x2 + 4x + 4 =0
在MathML中可以用以下的XML詞匯表示:
<apply>
<plus/>
<apply>
<power/>
<ci>x</ci>
<cn>2</cn>
</apply>
<apply>
<times/>
<cn>4</cn>
<ci>x</ci>
</apply>
<cn>4</cn>
</apply>
SMIL
SMIL(Synchronized Multimedia Integration Language,它的發音和"smile"一樣)是一種基於XML的表述多媒體演示的語言。SMIL允許將一組獨立的多媒體對象整合為一個多媒體演示。作為另一種行業趨勢,HTML+TIME依靠SMIL功能在你的HTML頁面中加入多媒體"時間"特性。現在IE 5提供了一個Html+TIME的實現。下面例子中的頁面中包含了一個時間序列。位於時間段中的每一個P元素會等到前一個P元素消失後再出現。
<Html>
<HEAD>
<STYLE>
.time { behavior:url(#default#time); }
</STYLE>
</HEAD>
<BODY>
<DIV CLASS="time" t:timeline="seq">
<P class="time" t:dur="1">
This appears for one second and goes away
</P>
<P class="time" t:dur="1">
This appears after one second, remains visible for one second
and goes away
</P>
<P class="time" t:dur="1">
This appears after two seconds, remains visible for one second
and goes away
</P>
</DIV>
</BODY>
</Html>
VML(Vector Markup Language)
矢量標記語言用於定義矢量信息編碼格式的一個XML應用,它和其他的標記一起決定了信息以何種形式顯示在屏幕上。VML對標記矢量圖形信息的支持和HTML對標記文本信息的支持是一樣的。一些微軟的產品(例如Microsoft PowerPoint? 2000)支持項文件導出到Html,使用VML來描述圖形信息。下面一段簡單的VML示例定義了一個形狀:
<v:shape style='top: 0; left: 0; width: 250; height: 250'
stroke="true" strokecolor="red" strokeweight="2" fill="true"
fillcolor="green" coordorigin="0 0" coordsize="175 175">
<v:path v="m 8,65
l 72,65,92,11,112,65,174,65,122,100,142,155,92,121,42,155,60,100
x e"/>
</v:shape>
CDF(Channel Definition Format)
CDF是一種開放的規格,它允許Web的發布者經常的更新信息或是頻道。而這些信息能從Web服務器自動的傳送到PC上的兼容接受程序或是其他的信息裝置上。用戶僅需選擇一下頻道,信息就會定時的傳遞到客戶端。當信息下載到客戶端後,CDF起到了頻道內容目錄的作用。
總結
除了上面我們列出的技術,XML相關的技術還有很多。我們將把對這些技術的探索留給你自己去完成。相信你已經感到,在XML及其相關技術發展的背後,有著巨大的、整個行業范圍內的努力在支持者它。
XML必將改變我們未來開發互操作性軟件的世界。如果想進一步了解XML對軟件組件技術的影響,請看Lessons From the Component Wars: An XML Manifesto(http://msdn.microsoft.com/library/en-us/dnXML/Html/XMLmanifesto.ASP)
想要深入學習有關XML的大量信息是比較困難的,人們往往很難看清所有這些東西是怎樣融合為一個整體的。這篇文章向你介紹了XML和它相關的一些技術。到目前為止,你已經大致明白了XML技術是什麼以及這些核心技術是怎樣整合在一起的。也就是說,你已經為今後進一步學習XML做好了准備!
參考內容
W3C規格和推薦閱讀材料
· Extensible Markup Language (XML) 1.0 (W3C Recommendation)
· Namespaces in XML (W3C Recommendation)
· XML-Data (W3C Note)
· XML-Schema Part 1: Structures (W3C Working Draft)
· XML-Schema Part 2: Datatypes (W3C Working Draft)
· Document Object Model (DOM) Level 1 Specification
· Resource Description Framework (RDF) Model and Syntax Specification
· XML Pointer Language (XPointer)
· XML Fragment Interchange Requirements Version 1.0
· Mathematical Markup Language (MathMLTM) 1.01 Specification
· XML XLink Requirements Version 1.0
· Vector Markup Language (VML)
· XHtmlTM 1.0: The Extensible HyperText Markup Language
· Channel Definition Format (CDF)
書
· XML In Action, by William J. Pardi, available at Microsoft Press. ISBN:0-7356-0562-9