完成WAP服務器的建立和WAP浏覽器的安裝之後,我們接下來就可以使用WML語言來編寫WAP網頁或應用,並通過WAP服務器及浏覽器進行調試。從本章開始我們將系統地學習WML語言,本章主要講解WML語言的基礎知識,下一章全面講解WML的語法、標簽和規則。
2.1 WML的簡單例子及編輯、測試方法
無限標記語言WML(Wireless Markup Language)是一種基於擴展標記語言XML(Extension Markup Language)的語言,是XML的子集。它可以顯示各種文字、圖像等數據,是由WAP論壇(http://www.wapforum.org)提出並專為無線設備用戶提供交互界面而設計的,目前版本為1.1版。這些無線設備包括移動電話,呼機和個人數字助理PDA(Personal Digital Assistants)等。
2.1.1 WML與WAP設備
為了更好的了解和使用WML語言,開發人員應對WML使用的設備和支持WML的設備的特點、特征有個大概的了解。
一般而言,WML使用的無線設備通常具有以下特點:
與普通的個人計算機相比,體積較小;
設備的內存有限,且其CPU性能也有限;
通訊帶寬較窄、時延較長。
以移動電話、PDA為例來講,支持WML的設備主要具有以下特征:
有一個顯示屏幕,可顯示2.凶址啃?2各字符;2.凶址型ǔ0ūA舾δ馨磁囊恍校?br>支持數字和字符的輸入;
支持操作者使用箭頭或數字按鈕進行選擇;
支持ASCII的可打印碼;
通常都有兩個可編程功能鍵,即Accpet鍵和Options鍵,一般安排在接近鍵盤的屏幕下方;
通常有一個Prev導航鍵。
我們介紹WML所使用WAP設備的目的,是希望讀者通過WAP設備的特點、特征來了解WML語言的特點,進而對WML編程所要解決的問題有個大概的認識。
2.1.2 使用文本編輯器面寫WML程序
使用WML語言編寫WAP網頁或應用時,需要使用一個編輯器進行編輯。與Html編程一樣,WML編寫的程序也是純文件文本,可以使用任意文本編輯器進行編寫,比如Windows系統中的“記事本(NotePad)”等。也可以使用比如Nokia WAP ToolkIE等軟件(有關此具體的用法會在以後的學習過程中提起)。我們先介紹第一種方法,隨後介紹第二種。
如果要使用"記事本(NotePad)"來編寫WML程序,則可以在Windows系統中,單擊“開始”按鈕,然後從出現的菜單中,依次將光標指向“程序”、“附件”、“記事本”,啟動“記事本”程序。屏幕上隨後就會出現它的編輯窗口,從中就可以輸入並編寫WML程序了。
作為舉例,我們可以輸入如下簡單的程序。
<?XML version="1.0"?>
<!DOCTYPE wml PUBLIC "-//wapforun//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.XML">
<XML>
<card id="card1" title="Title">
<P>
<!--Write your card implementation here.-->
Hello World!!
</P>
</card>
</XML>
輸完後將它保存為hello.xml文件。保存時注意文件的擴展名應為XML而不是txt。
2.2 WML程序結構
上一節我們降解了一個簡單的WML程序,具有HTML編程的讀者可以看出,WML程序在結構上形式上與Html程序有很多相似之處。下面我們就根據一個實例來分析一下WML程序的結構及組成。
2.2.1 WML的元素和標簽
分析實例之前,我們有必要對WML的元素和標簽予以簡單說明。與Html類似,WML的主要語法也是元素和標簽。元素是符合DTD(文檔類似定義)的文檔組成部分,如title(文檔標題)、IMG(圖像)、table(表格)等等,元素名不區分大小寫。WML使用標簽來規定元素的屬性和它在文檔中的位置。標簽使用小於號(<)和大於號(>)括起來,即采用“<標簽名>”的形式。標簽分單獨出現的標簽和成對出現的標簽兩種。大多數標簽是成對出現的,由首標簽和尾標簽組成。首標簽和尾標簽又分別稱為起始標簽和終止標簽。首標簽的格式為“<元素名>”,尾標簽的格式為“</元素名>”。成對標簽用於規定元素所含的范圍,比?lt;b>和</b>標簽用於界定黑體字的范圍,也就是說<b>和</b>之間包住的部分采用黑體字顯示。單獨標簽的格式為“<元素名/>”,他的作用是在相應的位置插入元素。如〈br/〉標簽表示在該標簽所在位置插入一個換行符。
2.2.2 WML程序結構形式及組成的實例分析
了解了上述知識後,下面我們在分析一個實例程序。程序如下:
<?XML version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapfourm.org/DTD/wml_1.1.XML">
<wml>
<card id="card1" ontimer="#card2" title="Tookit Demo">
<timer value="50"/>
<p aligh="center">
</br></br></br>
<big>
<!--Write your card implementation here.-->
Welcome to....
</big>
</p>
</card>
<card id-"card2" ontimer="#card 3"title="Toolkit Demo">
<timer value="50"/>
<p align="center">
<br/><br/>
<b>
The Nokia<br/>
</b>
Wireless Application Protocol
</u>
...
</p>
</card>
<card id="card3"title="Toolkit Demo">
<p align="center">
<br/><br/><br/>
<big>
<i>
Toolkit
</i>
</big>
</p>
</card>
</XML>
該程序運行後將在WAP手機屏幕依次顯示3屏信息。先顯示"Welcome to ...",然後顯示"The Nokia Wireless Application Protocol...",最後顯示"Tookit!"。顯示時每屏都有標題"Tookit Demo",相鄰兩屏之間延時為50,其單位大小為1/10秒,延時50即5秒。
通過以上實例我們可以了解到WML程序的結構形式及組成:
1)語法。WML與Html極為相似。仍然是一種標記語言,並且延續了XML的語法規則,具體的語法我們會以後的學習過程中遇到。
2)文件聲明。所有的WML程序必須在文件的開頭處聲明XML文件類型,包括XML的版本,WML的文檔類型、所用規范等。聲明形式如下:
<?XML version="1.0">
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.XML">
3)標簽。在WML語言中需要使用標簽(Tag),其使用形式與Html和XML等標記語言中的形式是完全一致的。
4)元素。WML的元素(Element)用於描述卡片組(Deck)的標記信息即結構信息。一個元素通常有一個首標簽、內容、其它元素及一個尾標簽組成,具有下述兩種結構之一:
<首標簽>內容</尾標簽>
或
<標簽/>
元素包含的內容中還可以有元素,這些元素也是有首標簽、相應內容、其它元素及尾標簽組成。不包含內容的元素成為空元素。它為一個單獨的標簽。或者說,單獨的標簽也是一種元素。
5)屬性。WML與XML一樣,其標簽可以包含很多屬性。屬性用於給標簽提供必要的附加信息,且屬性內容通常在起始標簽內使用。不過,屬性內容不會被浏覽器顯示,它至作為參數為標簽提供必要的信息。
指明屬性值的時候,需要把該值用引號擴起來,可以是單引號或者雙引號,引號通常成對嵌套使用。屬性名稱必須小寫。例如:<card id="card 1" ontimer="#card2" title="Toolkit Demo">
而且,單引號的屬性中還可以包含雙引號的屬性。實體字符也可以作為屬性值。實體字符是指諸如&、<、>、'、"的特殊字符,在WML程序中顯示著類字符需要特殊處理,後面我們介紹具體方法。
6)注釋。WML程序中也可以加入注釋。注釋內容用於給開發人員順利閱讀源代碼提供方便,它不會被浏覽器顯示出來。注釋內容在標簽中用感歎號(!)引出,並用於<!--注釋內容-->的形式。例如:<!-- Write your card implementation here.-->。需要說明的是,XML程序中不支持注釋的嵌套。
7)文檔結構。WML文檔是由“卡片(Card)”和“卡片組(Deck)”構成的,一個Deck是一個或多個Card的集合。當客戶端發出請求之後,WML即從網絡上把Deck發送到客戶浏覽器,這是用戶就可以浏覽Deck內包含的所有Card,而不必從網上單獨下載每一個Card,程序中的第一個Card是缺省得可見的Card。
注意:Deck是一副紙牌的意思,這裡是指一疊卡片,所以我們在這裡稱之為它為“卡片組”。另外,Card指的是WAP手機屏幕大小的網頁,盡管有時一個Card可能需要多屏才能顯示完,但我們也可以把它翻譯成“頁面”,不過這樣與Html中的頁面容易混合。因此我們在這裡稱之為卡片。
2.2.3 WML程序的基本結構
以上我們簡單分析了WML的程序結構及組成,由此大家可以對WML程序有個整體上的初步認識。下面我們給出WML程序的基本結構。
<?XML version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1XML">
<wml>
<head>
<Access/>
<meta..../>
</head>
<card>
Some contents...
</card>
<wml>
該基本結構可以分為以下幾個關鍵部分:
1)聲明。WML程序有許多Deck組成,對於每一個Deck,在其文檔開頭必須進行XML的聲明和文檔類型DOCTYPE的聲明。
XML聲明總是在文件的第一行,注意前面最好不要有空格或者還行:
<?XML version="1.0"?>
2)緊跟著是DOCTYPE聲明,注意聲明是字母的大小寫不要搞錯:
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1XML">
3)<xml>標簽。該標簽用於包含和定義WML的一個Deck。它有一個可選的xml:lang屬性來制定文檔的語言,比如<wml XML:lang="zh">表示文檔語言為中文。
4)<head>標簽。該標簽用於包含和定義Deck的相關信息。<head>標簽之間可以包含一個<Access>標簽和多個<meta>標簽。
5)<access/>標簽。它的一般形式是<access domain="域" path="/路徑"/>,主要用於制定當前Deck的訪問控制信息,有兩個可選的屬性。其中,domain用來制定域,默認值為當前域,path用來制定路徑,默認值為“/”,即跟目錄。由於<Access>單獨使用,所以要用“/”結尾,後面我們還會系統的講解WML的各種標簽,這裡即使看不懂也沒關系,主要有些感性的認識就可以了。
6)<meta...>標簽。它的一般形式是<meta 屬性 content="值" scheme"格式" forua="truefalse"/>,用於提供當前Deck的meta信息,包括內存數據處理方式,以及數據傳輸方式和處理方式等。有關該標簽的詳細內容我們後面會專門給出。
7)<card>標簽。一個Deck可以包含多個Card,每個Card的內容可能不止一屏顯示。對於每一個Card,WML均使用<card>和</card>進行包含和定義。 <card>同時可以包含多個可選的屬性,如<card id="name" title="label" newcontext="false" ordered="true" onenterforwand="url" pmemterbackward="url" ontimer="url">。至於這些屬性的具體含義及功能,我們將在後面介紹。
2.3 WML語言的基本知識
上一節我們介紹了WML程序的基本結構,接下來我們介紹WML語言的基本知識,主要包括WML的字符集、變量、數據類型及WML程序的基本組成部分等。
2.3.1 WML的字符集及編碼
WML使用XML的字符集,即通用字符集ISO/IEC-1062.,也即統一字符編碼標准Unicode 2.0。同時,WML還支持其他系列的字符集子集,例如UTF-8、ISO-8859-1或UCS-2等。其中:
UTF-8是指通用字符集UCS(Universal Character Set)的轉換格式8(Transformation Format 8),主要傳輸國際字符集的轉換編碼。UTF-8采用了UCS字符的8位編碼,提供了十分安全的編碼格式,可以有效避免數據傳輸過程中的竊聽、截取及非法解密。同時,UTF-8與7位ACSII碼完全兼容,不會影響此類編碼實現的程序;它的編碼規則十分嚴格,能夠有效避免同步傳輸錯誤,而且還會支持其它字符集提供了足夠的空間。
ISO-8859-1字符集是國際標准化組織ISO(International Standardization Organization)制定的ACSII字符集的擴展集,能夠表示所有西歐語言的字符。與ISO Latin-1一樣,ISO-8859-1與Windows環境中普遍使用的美國國家標准協會ANSI(American National Standards Institute)的字符集極為類似,絕大多數情況下無需區分。在不特別指明的情況下,HTTP協議均使用ISOLatin-1字符集。因此,為了WML頁面中表示非ACSII(non-ACSII)字符,開發人員需要使用相應的ISO Latin-1編碼的字符。
UCS-2是ISO 1062.標准中自定義的通用多8位編碼字符集(Universal Multiple-Octer Coded Character Set)的2字節(即16位)編碼標准,其字符編碼值與Unicode字符的標准編碼值相等。
WML文檔可以采用Html 2.0規范所定義的任何字符編碼標准經編碼處理。一般說來,WML文檔的字符編碼是需要轉換為另外的編碼格式,以與WAP用戶的手機浏覽器所用字符標准相適應,否則,手機浏覽器就無法顯示WML頁面中的字符。然而,編碼轉換時可能會丟失一些字符信息,所以,如果在用戶端進行WML文檔的編碼轉換,那麼就可能導致某些結果信息丟失而不能被用戶所浏覽。因此,如有必要,我們應當盡量在WML頁面傳送到用戶浏覽器之前完成編碼轉換。
為了解決這一問題,一方面,我們需要為Web服務器補充定義WML的數據類型,以讓服務器可以准確傳輸這些數據,另一方面,我們需要制訂編碼轉換的原則。
2.3.2 WML字符使用基本規則
WML是一種比較嚴格的語言,字符使用必須遵守相應的規則,這些基本規則主要包括以下幾個方面:
1)大小寫敏感。在WML中,無論是標簽元素還是屬性內容都是大小寫敏感的,這一點繼承了XML的嚴格特性,任何大小寫錯誤都可能導致訪問錯誤。
一般來說,WML的所有標簽,屬性,規定和枚舉及它們的可接受值必須小寫,Card的名字和變量可大寫和小寫,但它是區分大小寫的。包括參數的名字和參數的數值都是大小寫敏感的,例如variable1、Variable1和vaRiable1都是不同的參數。 2)空格。對於連續的空字符,程序運行時只需要一個空格。屬性名、符號(=)和值之間不能有空格。
3)標簽。標簽內屬性的值必須使用雙引號(")或單引號(')括起來。對於不成對出現的標簽,必須在大於號(>)前加上順斜槓(/),比如換行標簽必須寫成<br/>才正確。
4)不顯示的內容。在WML中,不顯示的字符主要包括換行符、回車符、空格和水平制表符,它們的8位十六進制內碼分別為10、13、32及9。
程序執行時,WML將忽視所有的多於一個以上的不顯示字符,即WML會把一個或多個連續的換行、回車、水平制表符及空格轉換成一個空個。
5)保留字符。這是WML的一些特殊字符,如小於號(<)、大於號(>)、單引號“'”、雙引號“"”、和號(&)。
6)顯示漢字。如果希望WML程序執行時能夠顯示漢字,則只需要程序開頭使用encoding指定漢字字符集即可。例如:<?XML version="1.0" encoding="gb2312">。
注意:指定漢字字符集的形式和方法可能因為開發工具或WAP手機的不同而不同。
2.3.3 變量
WML編程中可以使用變量,變量使用前必須進行定義。變量一旦在Deck中的某一個Card上定義過,其他Card則可以不必重新定義就能直接調用該變量。
定義變量的語法格式為:
$identifIEr
$(identifIEr)
$(identifIEr:conversion)
其中identifIEr指變量名,或說變量標示符;conversion指變量的替代。
變量名是由US-ACSII碼、下劃線和數字組成的,並且只能以US-ACSII碼開頭。變量名嚴格區分大小寫,也即,變量名是大小寫敏感的。
定義變量的語法在WML中享有最高的解釋優先級。
有關變量的使用說明如下:
1)在WML中,變量可以在字符串中使用,並且在運行中可以更新變量的值。
2)當變量等同於空字符串時,變量將處於未設置狀態,也就是空(Null)。
3)當變量不等同於空字符串時,變量將處於設置狀態,也就是非空(Not Null)狀態。
4)在“$identifier”形式下,WML通常以變量名後面的一個空格表示該變量名的結束。如果在某些情況下空格無法表示一個變量名的結束,或者變量名中包含有空格,則必須使用括號將變量名括起來,即采用“$(identifIEr)”的形式。
WML程序中的變量是可以替代的,我們可以把變量的數值賦給Card中的某一文本。有關變量替代說明如下:
1)在WML程序中,只有文本部分才可以實現替代。
2)替代一般在運行期發生,而且替代不會影響變量現在的值。
3)任何標簽是按照字符串替代的方式實現的。
4)替代是按照字符串替代的方式實現的。
由於變量在語法中有最好的優先級,包含變量聲明字符的字符串將被當作變量對待,所以如果要使程序顯示“$”符號,則需要連續使用兩個“$”進行說明。例如:<p> Your acconut has $$15.00 in it </p>一句顯示的結果為:Your account has $15.00 in it。
2.3.2. WML核心數據類型
WML的核心數據類型均屬於字符型數據,是根據XML的數據類型定義的,共有下述2.擲嘈停?1)CDATA型。這種數據類型是WML用得最多的一種,可以是數字、字符串或包含數字的字符串。不過定義時,不論是數字或字符串,都必須以文本的形式定義,及數據用引號引起來。CDATA型的數據僅用於屬性值。例如"$(value)"或name="value"等。注意,這裡的value指CDATA型的數據值。
2)PCDATA型。這是從CDATA中分解出來的一類數據,除了可以是文本形式的數字、字符串或兩者的混合串外,還可以是WML的標簽。PCDATA型的數據只能用於WML的元素表示。
3)NMTOKEN型。這是一類特殊的數據,凡是包含或部分包含數字、字母及標點符號的數據均屬於NMTOKEN型數據。這種數據可以用標點符號開頭,但不用於定義變量名或元素名。
4)id型。專門用於定義WML元素名稱的數據類型。
在這2.擲嘈橢校珻DATA型用起來比較靈活,它可以使變量或數據免於語法檢查。這是因為,CDATA內的數據內容都會被當作文本來處理,從而可以避免WML的語法檢查,直接作為文本顯示出來。
2.3.5 WML數據值性質
除了NMTOKEN型數據外,WML其他3種數據都必須以文本形式即加上引號進行定義。我們關心的問題是,這些類型的數據可以表示哪些數據值呢?或者說,它們所表示的數據值的性質是什麼呢?
事實上,WML數據只在性質上可以是長度(Length)、宏變量(Vdata)、流(Flow)、內行(Inline)、布局(Layout)、文本(Text)、超鏈(Href)、布爾值(Boolean)、數據(Number)或增強方式(Emphasis)。
2.3.6 卡片與卡片組
前面我們分析了WML程序的結構時,曾將講到WML文檔的信息是通過卡片集和卡片組集的形式進行組織的。一個Deck是一個或多個Card的集合。當客戶終端發出請求之後,WML即從網絡上把Deck發送到客戶的浏覽器,Deck是服務器發送信息的最小單位。用戶浏覽器收到Deck後,可以浏覽其中包含的所有Card。Card用於表示或描述一個或多個用戶交互單位。
2.3.7 卡片組模板
同一卡片組通常會含有許多卡片,這些卡片的定義、屬性或格式通常都大同小異。如果我們逐一定義各個卡片,顯然是十分麻煩的。為此,WML提供了卡片組模板的功能,模板內定義了一系列標准和參數,可以應用到同一卡片組的所有卡片中去,從而能夠大大地提高我們的編程效率。有關卡片組模板的內容我們後面會專門介紹的。
2.3.8 WML與URL、程序段錨點
我們知道,環球網WWW是各種信息和設備的網絡,為保證全球范圍內的交互,人們制定了3種規范:其一,統一資源定位器URL提供所有網絡資源的標准命名方式和定位方式;其二,標准協議,如HTTP協議等,提供WWW資源的傳輸方式;其三。標准內容類型,如Html、WML,提供WWW資源的內容形式及標准。WML沿用了這些規范,並擴大了URL使用的范圍。在WML中,不僅超連接、文件路徑及文件名可以作為URL處理,卡片名、宏變量名及各種內部資源名等也可作為URL處理。
為此,WML改進了Html命名資源位置的方式,采用程序錨點(Fragment Anchor)的形式來處理WML程序中某段程序的地位。程序段錨點根據文檔WML規則進行定義,並按照程序段表示符前加井字好(#)的方式書寫。使用程序段錨點,WML程序可以在同一卡片組中定位不同的卡片。如果在程序中不指定程序段,那麼程序中引用的URL名稱則指整個卡片組,而且卡片組的名稱同時也是本卡片組內的第一個卡片的名稱。 2.3.9 浏覽器操作歷史
為了在浏覽器端管理WML程序的執行,WML使用“浏覽器前後關系”的功能保存WML程序執行的狀態及各種參數、變量等,這樣可以用來記錄用戶的操作情況。同時,WML還提供了一個簡單的導航歷史模型,以URL地址的形式記錄了用戶浏覽時的各種操作,並把這些URL地址放入歷史推棧。通過推棧,用戶即可實現歷史浏覽的回潮及其它操作。