i-world-i-dream

 

WAP建站进阶

 

WAP建站进阶

   在对WAP的概念有了初步的了解之后,读者将要重点学习如何使用WML标记语言和WMLScript脚本语言进行开发。本章首先介绍了一些流行的WAP工具包,然后深入浅出地介绍了WMLWMLScript,并且还有详尽的实例供初学者参考。详细的WML标记和WMLScript函数库是难得的中文参考资料

一、WAP工具包

  目前WAP技术还处于初步的发展阶段,但是它的出现引起了公众的强烈兴趣。WAP业务在欧洲开展得较早,目前将有更多的业务在北美和亚洲展开。很多WAP开发商推出了一些WAP应用工具,以进一步加快WAP应用的发展

WAP工具包

    目前WAP技术还处于初步的发展阶段,但是它的出现引起了公众的强烈兴趣。WAP业务在欧洲开展得较早,目前将有更多的业务在北美和亚洲展开。很多WAP开发商推出了一些WAP应用工具,以进一步加快WAP应用的发展。在这里将要介绍一下目前四个主流的WAP工具包:

    • Ericsson WapIDE 2.0
    • Nokia WAP Toolkit 1.2
    • Phone.com UP.SDK 4.0
    • Motorola ADK 1.0

    虽然这四家公司都是WAP论坛的主要成员,但是他们的开发工具包在很多方面都有所不同。如果读者正打算开发第一个WAP应用,建议使用Nokia WAP Toolkit作为入门工具。阅读工具包中所带的例子是学习WAP好方法。下面主要整体介绍各种工具包,具体的功能与操作可以参考前面对Nokia WAP Toolkit的功能介绍。


Ericsson WapIDE 2.0

    Ericsson WapIDE 2.0具有集成化的WAP开发平台。它由一系列能支持设计和WAP测试的应用工具构成。同时它支持自己设计和更换测试设备的外形。WapIDESDK目前只能在Windows NT 4.0Windows 95/98下使用。在WapIDE中还有用于测试服务器应用的程序。这些包括Perl 5.0Tcl/TkXitami Web Server。安装WapIDE需要首先安装IDE,然后安装SDK。还需要注意的是:如果不安装Xitami Web服务器,那么整个安装过程就失败了。所以如果读者已经有了其他的Web服务器,可以先关闭它。等安装完成后关闭Xitami Web服务器,再恢复原来的Web服务。在安装的时候,最好安装全部功能选项。如果不需要Xitami Web服务器,那么就不要选择Xitami Web服务器自动启动这一项。否则在重新启动机器的时候IIS会与Xitami Web服务器产生冲突!


3-1 WapIDE 2.0

    3-1所示是WapIDE的一个界面,其中包括浏览器(用于测试应用程序)、应用设计器(用于编写应用程序)和一系列服务器端工具集(一些工具诸如:WML/WMLScript编译器和一个语义分析器)。


3-2 浏览器

    浏览器(图3-2)支持使用不同的设备(缺省情况下设备显示的是R320s的样子),允许使用者测试工具包中带有的WAP URLs例子,或测试自己编写的应用,这些WAP应用例子包括金融、股票和日程等的应用。在使用这个浏览器的时候有一个十分有意思的事情:必须按住开机按钮,才能启动浏览器并开始使用。否则,读者就会弄不懂它为什么不工作。
    读者的大部分时间将会花费在应用程序设计上。这个部分集成了一个WML编辑器和一个WapIDE浏览器,这样编程序和测试将在一起实现。这是一个十分朴素的开发环境,相关文档也比较少,只有一些Adobe Acrobat的文档可供下载。


Nokia WAP Toolkit 1.2

    NokiaWAP工具包在某些方面很类似于EricssonWapIDE。两个产品都有图形开发环境、浏览器和WML/WMLScript编译器。Nokia工具包目前只能在Windows NT 4.0上运行。要注意的是Nokia WAP Toolkit需要Java运行环境。所以需要先到SunJava站点下载一个Java 2 SDK或者Java 2 Runtime EnvironmentJRE)才可以安装和使用Nokia WAP Toolkit
    工具包安装完之后,可以看到WAP工具包程序组中包括一个工具包IDE。还有很多关于WAPWMLWMLScript的详细文档以及工具包本身的使用指导。该工具包支持在同一个应用下进行编辑、修改和测试WML/WMLScript文件等工作。
    用户可以通过输入WAP应用的URLs或通过WAP网关进行浏览网页。Nokia还出售一个独立的基于WAP 服务器的Java Servlet。该产品将应用服务器功能和WAP网关功能集成到一个产品中。总体来说,Nokia WAP产品相对于Ericsson WapIDE产品显得较成熟、实用。


Phone.com UP.SDK 4.0

    Phone.com公司的UP.SDK产品适用于Windows 95/98/NT Solaris。与NokiaEricsson的产品有稍许区别,它不带有图形的IDE。也没有提供编辑和测试WML/WMLScript程序代码的集成环境。UP.SDK更着重于提供一系列可由不同语言(如:WMLPerlCC++VB等)重复使用的代码库。Phone.comWAP微浏览器制造的领先者,很多WAP手机中采用的都是Phone.com公司提供的WAP微型浏览器。模拟器UP.Simulator如图3-3所示。模拟器目前只能在Windows平台上运行。


3-3 UP.Simulator

UP.Simulator在启动的时候将自动连接Phone.com开发者站点,所以需要保持与Internet的连接。UP.Simulator无法脱机使用,也无法直接打开WML文件。推荐大家去试用一下该产品,它会很直观地让读者感觉到WAP的用途。在一两秒之内就能使用UP.Simulator查到本地的天气情况,看到世界各地的新闻。UP.SDK还包括有供PerlC语言使用的库函数,可以用来生成WML文件,控制HTTP请求等。另外,UP.SDK有请求并安装SSL证书的安全性工具。Phone.com除了提供标准的WAP功能外,它还扩展了更多的WAP功能如传真、通知等。


Motorola Mobile ADK 1.0

    从总体上来说MADK提供了一个完整的集成开发环境和浏览器。使用的时候会发现它的工作方式和Visual Studio的工作方式很像(图3-4)。因此对于习惯于使用微软产品的开发人员来说将是十分顺手的。另外MADK还提供了比较完整的帮助文档,里面除了介绍WMLWMLScript以外,还介绍了VoXML


3-4 MADK集成开发界面

3-5 模拟器

    如果操作系统为WinNT或者Win98,那么在安装MADK之前必须更新Java虚拟机,否则安装过程就会失败。在安装的过程当中,还将附带地安装Voice Agent。在使用的过程当中,读者会发现MADK不如Nokia WAP Toolkit成熟。例如:如果直接输入中文,就会引起编辑界面的混乱;在每次模拟完成之后,必须停止模拟器(图3-5)再重新打开,否则无法进行新的测试工作;再每次编译之后留下一大堆的WMLC文件;更奇特的是在Nokia WAP Toolkit编译通过的页面,在MADK上就可能通不过。


其他工具包

工具包

编辑器

模拟器

调试工具

例子程序

在线文档

Nokia WAP Toolkit 1.2
http://forum.nokia.com/main.html

MADK 1.0
http://www.motorola.com

WapIDE SDK 1.2
http://www.ericsson.com/developerszone/

UP.SDK 4.0
http://www.phone.com

WAPObjects
http://www.wapobjects.com/wapobjects/en/

WAPPage 1.0
http://www.wapmine.com/Products.asp

CardONE
http://www.peso.de/wap_en/index.htm

WAP Developer Toolkit 1.0
http://www.dynamical.com/wap/index.html

PWOT WML Tools
http://pwot.co.uk/wml/

二、WML简介

   WML是一种基于XML(扩展标记语言)的一种标记语言。这种语言是为无线设备用户提供交互界面而设计的。这些无线设备包括电话、呼机和个人数字助理(Personal Digital Assistants)等等。

 

   WML是一种基于XML(扩展标记语言)的一种标记语言。这种语言是为无线设备用户提供交互界面而设计的。这些无线设备包括电话、呼机和个人数字助理(Personal Digital Assistants)等等。
    WML是为具有以下特点的设备而设计的:

  • 体积小(相对于个人计算机)。
  • 有限的内存和CPU大小。
  • 通讯带宽窄和时延长。

    现在支持WML的设备大致分为两大类:

  • 电话棗其特点就是只有4~10行的文本屏幕。用户通过电话的按钮进行输入。
  • 个人数字助理(PDA)棗其特点就是能支持100×100分辨率(或者更好)。用户能够通过键盘、鼠标或者手写输入。

    现在正期待着其他的手持设备同样能支持WML
    因为WML支持许多功能不同的设备,因此文档中列出了这些设备至少应有的功能或者是参考设备。参考设备有以下的特点:

  • 有一个显示屏幕,能显示4行字符,每行12个字符。包括保留给功能按钮的那一行。
  • 支持ASCII的可打印码。
  • 支持数字和字符的输入。
  • 支持使用箭头或者数字按钮进行选择。
  • 两个可编程功能键,ACCEPTOPTIONS,并且显示在接近键盘的屏幕下。
  • 一个PREV导航键。
  • 支持垂直滚动的箭头按键。
  • 支持水平滚动(不是使用自动换行)。

字符集

    WML使用XML的字符集棗也就是当前使用的通用的字符集ISO/IEC-10646Unicode 2.0)并且支持其他系列的子集(例如:US-ASCIIISO-8859-1或者UTF-8)。不必使用整个UnicodeUCS-4)编码,除非正在使用的不是UTF-8编码。

大小写敏感

    不象HTMLWML是一种大小写敏感的语言。所有的标签、属性和枚举属性都必须使用小写。在编写WML页面的时候,必须注意到大小写。包括参数的名字和参数的数值都是大小写敏感的。例如:variable1Variable1vaRiable1都是不同的参数。

不显示的字符

    3-2中包括了在WML中不显示的字符:

  3-2 不显示的字符

字符

8位十进制值

换行

10

回车

13

空格

32

水平制表符

9

除非特别的指定,WML将一个或多个连续的换行、回车、水平制表和空格转换成一个空格。换句话说,忽略所有的多于一个以上的不显示字符。

例子1

<wml><card><p>Some text</p></card></wml>

例子2

<wml>
    <card>  
      <p>
        Some text  
      </p>
    </card>
</wml> 

    上面的例子中,手工地使用换行和回车保证程序的可读性,但不是很必要。

文件开场白

    所有的WML页面必须在文件的开头处声明XML文件类型:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"  "http://www.wapforum.org/DTD/wml_1.1.xml">

    为了将这个开场白自动地加入到页面中,读者可以使用函数调用来实现。

    注意:为了确定WAP浏览器的类型和版本,可以通过捕获HTTP头中的USER_AGENT来进行。

Content Type

    为了建立一个有效的WML信息实体(MIME type),必须在文件的开场白之前指定文件的类型:

Content-type: text/vnd.wap.wml

    注意:必须(至少)在Content TypeXML文件声明之前保留一段空行。如果省略了,将造成编译器错误。过多的空行同样也会造成错误。

属性

    许多WML标记有一个或多个属性标记,有些是必须的,有些是可选择的。属性可以指定附加的信息,用来确定设备如何解释这些标签。WML标记有以下两种使用方式:

      • <element a1="value1" a2="value2" ...> content </element>
      • <element a1="value1" a2="value2" .../>

    必须使用成对的单引号或者双引号将属性值包含在内,每个属性之间使用空格分开。

引用变量

    很像UNIX下的Shell变量,可以在格式化的文本、URL、选择文本等等文本内容中使用变量。
    使用变量的语法如下:$(myvar)

特殊字符

    WML的保留字符:“<”、“>”、“'”、“"”和“&”。为了在文本中显示这些字符,必须按照表3-3中规定的方式指定。

3-3 指定特殊字符

字符

指定方式

&lt;

&gt;

&apos;

"

&quot;

&

&amp;

$

$$

连续空格

&nbsp;

-

&shy;

    分号是字符标签的一个部分,不能省略。如果省略了,将可能会造成WML编译器错误。
   
注意:与HTML不同的是,当在URL中使用&的时候必须使用&amp;来代替字符&

二、WML重点

在对WML有初步了解的基础上,下面将要讲述的是WML语法中的重点部分。了解这些部分就等于对WML有了一个比较全面的了解

 

基本规则

    WML使用XML文档字符集,目前支持Unicode 2.0。与HTML不同,WML的所有标签、属性和规定的枚举值必须小写。卡片的名字和变量也是区分大小写。和HTML一样,对于连续的空字符,只显示一个空格。标签内属性的值必须用双引号或者单引号括起来。属性名、等号和值之间不能有空格。对于不成对出现的标签,必须在“>”前加“/”。比如:<br/>。在对变量的引用上和HTML基本相同,有以下三种形式:

  • $(var1:esc)
  • $(var1:noesc)
  • $(var1:unesc)

    三种形式,具体含义可参见HTML的相关部分。在对保留字符的处理上也基本相同,对应的替代字符请详见“字符实体”。这里要指出的是在URL的传递过程中,用来连接参数的&必须转化为&amp;

基本格式和文件头

    wml文件的一般格式:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <head>
        <access/>
        <meta..../>
    </head>
    <card>
        Some contents...
    </card>
<wml>

    结构看上去和HTML文件很类似,对于每一个页面,在其文档开头必须指明以下的类型声明:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">

    千万注意字母的大小写。对于一个页面,其文件大小最好不要超过1.2K
    <wml>标签和HTML中的<html>标签一样,用来表明这是一个WML的页面。它有一个可选的“xml:lang”属性来制定文档的语言,比如<wml xml:lang="zh">表示文档语言为中文。
    HTML一样<head>标签包含了该页面的相关信息。<head>标签之间可以包含一个<access>标签和多个<meta>标签。
    <access domain="" path="/路径" />相当于HTML中的<BASE>标签,指定该页面的访问控制信息。它用两个可选的属性,domain用来指定域,默认值为当前域;path用来指定路径,默认值为“/”,即根目录。由于<access>单独使用,所以要用“/”结尾,以后对于类似的情况不再赘述。
    <meta 属性 content="" scheme="格式" forua="true|false"/>HTML中的类似,提供了该页面的meta信息。属性是必选的,包括以下三种情况:

    • name="name" UP.Link Server忽略meta数据。
    • http-equiv="name" UP.Link Servermeta数据转为HTTP响应头(同HTML)。
    • user-agent="agent" UP.Link Server直接将meta数据传给手机设备。

    content属性也是必选的,其内容根据属性而定。scheme属性目前尚不支持。forua为可选属性,指定在该wml文件传到客户端之前,<meta>标签是不是被中间代理删除(因为传输的协议可能改变),默认值为false
    目前支持的meta数据:

  • <meta http-equiv="Cache-Control" content="max-age=3600"/>

    指定页面在手机内存缓存中的存储时间段,默认的为30天(除非内存耗尽)。在此期间,手机对于访问过的页面直接从缓存里调用。如果信息是对时间敏感的,可以用max-age指定页面在缓存里的生存期,最小单位是秒。如果指定为0,则每次都需通过连接服务器来调用该页面

  • <meta user-agent="vnd.up.markable" content="false"/>
    <meta user-agent="vnd.up.bookmark" content="
    指定的URL"/>

    类似于普通浏览器的书签功能。当用户将一个卡片做了书签后,手机浏览器首先用一个标记记录该卡片。这个标记默认的是<card>标签中的title属性(以后会讲到)。然后当用户选择了该书签以后,浏览器就会打开被记录的URL。但是因为在默认的情况下,手机会记录所有的页面。所以,一般<meta>被用来使手机不要记录当前的URL,即<meta user-agent="vnd.up.markable" content="false"/>。此外,如果要为书签指定不同于当前页面的URL,用<meta user-agent="vnd.up.bookmark" content="指定的URL"/>
    一个页面可以包含多个卡片,每个卡片的内容可能不止一屏显示,注意页面、卡片和屏幕显示范围的关系。一个卡片用<card></card>包含。<card>可以包含以下可选的属性:

    <card id="name" title="label" newcontext="false" ordered="true" onenterforward="url" onenterbackward="url" ontimer="url">

  • id属性用来指定卡片的名字,可用来在卡片间跳转,相当于在HTML中在页内跳转时用<A NAME="jumpHere">
  • title属性用来作为书签的标记,该属性一般不会显示在屏幕上。
  • newcontext属性(默认值为false)用来指示当跳转到本卡片时,手机是不是要清除以前保留的信息。包括变量、堆栈里的历史记录、重新设置手机状态等。
  • ordered属性(默认值是true)表明该卡片里的内容是按固定的顺序显示,还是按用户的选择顺序来显示。这点和HTML不同,卡片里的内容可以按一定的顺序显示。默认的是按线性顺序显示,即按代码的顺序。但是,要注意的是,以下三个标签必须按以下顺序来写:<onevent><timer><do>(这和以后要讲的事件有关)。这样做是为了方便填表单,当ordered设置为true时,如果一个表单的内容不能在一屏里显示完,就分成多屏显示;当ordered设置为false时,手机可以显示一个概要卡片来总结有效的选项,用户可以从中选取表单选项来填写。

    onXXXX属性,类似于HTML标签中的onXXXX属性,用来捕捉事件。当事件被触发时执行指定的操作(任务),在这里是转向某个URL

显示文本

 

    在文本的显示上WML基本和HTML相同。文字段落包含在<p align="alignment" mode="wrapmode"></p>之间。align属性指定该段文字的对齐方式,默认的是left。其他可选择rightcentermode属性指定当一行显示不下所有的文字时是否自动换行。默认的是自动换行wrap。如果选nowrap,则在一行中显示,浏览器会通过类似于水平滚动条的机制来显示所有文字。
    换行标签也一样为<br/>。这里先提一下,在表单中如果有多个<input>或者<select>,其间不要用<br/>,否则会使手机浏览器认为是断点而把表单分页显示。
    文字的修饰标签有<b><i><u><em><strong><big><small>,意义和HTML里的相同。
表格的显示标签也和HTML相近,使用<table title="name" align="left|right|center" columns="列数"><tr><td>来显示。<table>title属性用来给表格取个名字,columns属性指定表的列数,不能为0。可选的align属性和前面提到的一样是对齐方式。表格中可以包含文字和图片。
    请研究下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <card>
        <p align="center">
            <i>Hello</i>
            <b><i>World!</i></b>
            <table title="mytable" align="right" columns="2">
                <tr>
                    <td>1-1</td>
                    <td>1-2</td>
                </tr>
                <tr>
                    <td>2-1</td>
                    <td>2-2</td>
                </tr>
            </table>
        </p>
    </card>
</wml>

3-6是使用Nokia WAP Toolkit的测试结果(表单很漂亮!)。


3-6 表单测试结果

显示图片

显示图片(1位黑白BMP图片)的标签一样类似于HTML

    <img alt="text" src="url" localsrc="icon" align="left" height="n" width="n" vspace="n" hspace="n"/>

    属性中altsrc是必须要有的,其他是可选的。另外要注意的是<img>要放在<p>里,不能放在<do><option>等功能健标签和选单标签里。

  • alt属性用来指定当手机不支持图片显示时用来显示的文字。
  • src属性指定图片的URL,但当有了以下的localsrc属性时,手机浏览器就忽略src属性。
  • localsrc属性用来指定显示存在手机ROM中的图标,如果找不到,则到UP.Link Server上去找。
  • 可选的align属性用来表明图片同当前行文本的对齐方式,默认值为bottom,可选tomiddle
  • heightwidthvspacehspace属性分别指定图片的长宽和距环绕文字的间距,目前不是所有的WAP手机都支持这些属性。

    请研究下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <card>
        <p align="center"><img alt=":)" src="xxx.bmp" localsrc="smileyface"/></p>
    </card>
</wml>

锚和任务

    链接是HTML页面里最基本的功能,在WML里也一样用<a href="url" title="label"></a>来包括用来建立链接的文字。必选属性href指定了要打开的URL;可选的title属性给该链接取个标记名字,这个名字将作为软按钮之一的ACCEPT键的标记显示在屏幕的软按钮区,所以通常可以将属性作为提示文字使用。
    然而,以上的链接在WML里只是任务的一种情况。为了能够使用其他任务,所以引进了新的标签<anchor title="label">任务标签文本</anchor><a>其实是当任务标签为<go/>时的简单表示方式。

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card>
    <p>
        <anchor title="Link1"><go href="test1.wml"/>News</anchor><br/>
        <a title="Link2" href="test2.wml">Sports</a>
    </p>
</card>
</wml>

    WML里的任务标签有以下几种,除了用于<anchor>,还可以用在事件中:

·         <go>

用来指示浏览器显示指定的URL,包括页面的第一个卡片或者指定的卡片。语法如下:

<go href="url" sendreferer="false|true" method="get|post" accept-charset="charset">
  <postfield name="name" value="value"/>
  <setvar name="name" value="value"/>
</go> 

其中href属性为必选,其他属性为可选。

    sendreferer属性表示是否传递调用href所指定的URL的页面的URL。也就是当前页的URL,即HTTP头中的HTTP_REFERER。默认值为false,可选值为true
    methodHTML中的表单FORMmethod属性一样,指定表单是以get的方式还是post的方式递交,以便CGI处理。默认的值为get,但如果未指定method<go></go>间存在<postfield>,手机自动以post方式传递。
    accept-charset属性可以覆盖HTTP头里指定的字符集。可以写多个字符集,如accept-charset="UTF-8,US-ASCII, ISO-8859-1"
    <postfield name="name" value="value"/>可以看作是HTML表单FORM中的<INPUT TYPE="HIDDEN" NAME="变量名" VALUE="">,通过它可以向指定的URL传递以“变量名/值”形式的数据。namevalue属性都是必选的。注意只有这里的变量是用来递交给CGI程序的。
    除了<postfield>,还可以在<go></go>之间加入一句或者多句<setvar name="name" value="value"/>。该语句的意思是,当触发某一事件时,给变量赋值。
    要注意的是:当<go></go>之间没有任何语句时,要用<go/>的形式,这点比较特别。比如:<anchor title="Link1"><go href="test.wml"/>News</anchor>

·         <prev>

    用来将当前页面的URL压入URL历史堆栈,并打开此前的URL。若该URL不存在,则<prev>无效。语法类似<go>

        <prev><setvar name="name" value="value"/></prev>

    <prev></prev>之间可加入一句或多句<setvar name="name" value="value"/>。若不加,则必须变成<prev/>的形式。

·         <refresh>

    用来刷新当前的页面,从而使得页面内的变量刷新,语法为:

        <refresh><setvar name="name" value="value"/></refresh>

·         <noop>

    表示什么也不做。该标签不能用在<anchor>中,一般用在覆盖页面级的事件模板。

显示表单

    类似于HTML<FORM><fieldset>可用来包括一组表单选项,但不是必须的。前面说过,当<card>ordered设置为false时,手机可以显示一个概要卡片来总结有效的选项,方便用户从中选取表单选项来填写。概要卡片就是根据<fieldset>和独立的输入框<input>以及选单<select>来总结的。语法为:

        <fieldset title="label">表单内容</fieldset>

 可选的title属性除了可以用来表示表单的名字外,还在概要卡片里作为选择项的标题。表单内容可以是嵌套的<fieldset>,输入框<input>,选单<select>和必要的提示文本。

    <input name="variable" title="label" type="type" value="value" default="default" format="specifier" emptyok="false|true" size="n" maxlength="n" tabindex="n"/> 

    用来输入文本,除了name属性是必要的,其他可选。

  • name属性,指定了用来存储该输入文本的变量名字。
  • title属性,该输入框的名字,同样可被用来作为概要card页中的选项名。
  • type属性,默认值为text,如选择password,则输入的数据显示为*
  • value属性,在语法和行为上等同于下面的default属性。
  • default属性,指定输入框的默认值,即name属性指定变量的默认值,当用户输入新值时,该值无效,如果该值不符合以下format属性的规定,则手机忽略该默认值。
  • format属性,用来格式化输入的数据,可用的标记如下,使用时可用一位数字标记“*标记的形式,前者代表N个标记型字符,如3X,后者代表任意个(小于maxlength属性的值)标记型字符。表3-4中包括了在format中常用的枚举数值及其意义。

3-4 格式化标记

标记

描述

A

任何符号或者大写字母(不包括数字)

A

任何符号或者小写字母(不包括数字)

N

任何数字(不包括符号或者字母)

X

任何符号、数字或者大写字母(不可改变为小写字母)

X

任何符号、数字或者小写字母(不可改变为大写字母)

M

任何符号、数字或者大写字母(可改变为小写字母)或者多个字符,默认为首字大写

M

任何符号、数字或者小写字母(可改变为大写字母)或者多个字符,默认为首字小写

  • maxlength属性,指定了用户可输入的最大字符长度,最大限制为256个字符。
  • emptyok属性,表示用户可否不填输入框,默认为false,即要填。
  • size属性,输入框显示长度,目前未被支持。
  • tabindex属性,类似于在HTML表单中按TAB键后,焦点落在哪个选项上,该值决定了选择顺序,数字大的排在后面。目前未被支持。

    为了说明输入格式对用户的影响,请看下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <card id="card1" ordered="false">
        <p>
            USERNAME:<input name="userName" title="User Name" type="text" value="YourNameHere" format="*M" emptyok="false" maxlength="12" tabindex="1"/>
            PASSWORD:<input name="password" title="Password" type="password" format="8x" emptyok="false" maxlength="8" tabindex="2"/>
            COMMENTS:<input name="comments" title="comment" type="text" value="YourCommentsHere" format="*M" emptyok="true" maxlength="30" tabindex="3"/>
        </p>
    </card>
</wml>

    启动Nokia WAP Toolkit,并选择“Go”下的“Open Location”,在输入URL地址后,可以看到模拟器上出现图3-7所示的内容。注意光标默认地指在PASSWORD的编辑框内。


3-7 用户输入界面

    选择“Options”进行编辑,多按几次按钮。在输入没有满8个之前选择“OK”,模拟器没有任何反应;当超过8个以后就无法再输入。这就是8x的限制在起作用。并且由于PASSWORD输入属性type为“password”因此显示出来的都是“********”(图3-8)。要注意的是:在输入的时候不要太快,否则总在一个字符上切换。如果读者用过手机,应该知道这点。


3-8 Password输入界面

    在删除所有的字符时候,“Clear”变成了“Back”(图3-9)。模拟器返回以前的页面。


3-9 删除所有的字符

    当编辑“User Name”的时候,发现输入的自动都变成大写(图3-10)。这是因为M起作用。如果输入超过12个字符,那么将无法再输入字符。这是maxlength在起作用。


3-10 编辑User Name

    当然可以使用这个按钮,将输入方式切换到小写(图3-11)。


3-11 切换大小写的按钮

    现在可以输入小写字符了!(图3-12


3-12 输入小写字符

    如果这个时候按“OK”,那么USERNAME就变成了“GJTMW.g”(图3-13)。这是由于M前面是“*”的缘故。它不限制输入字符的数目。但是如果将“User Name”中所有的字符清除,再选择“OK”就不行。这是emptyok在起作用。它要求至少输入一个字符。读者自己试试吧!


3-13 User Name已经改变

    将上例<card>中的ordered的值改为“true”试试看,然后再在<p></p>内加入<fieldset title="field1"></fieldset>试试看。(Nokia WAP Toolkit好像对这些变化视而不见……)

    <select>选单类似于HTML表单中的<SELECT><select></select>间可包含<optgroup><option>标签,语法如下,所有属性都为可选:

        <select title="label" multiple="false|true" name="variable" default="default" iname="index_var" ivalue="default" tabindex="n">
            <optgroup title="label">选单内容</optgroup>
                <option title="label" value="value" onpick="url">
                    事件或者文本
                </option>
    </select>

  • title属性,如以上<input>title属性。
  • multiple属性,指定用户可否进行多项选择,默认值为false
  • name属性,用来存储用户选择项的变量名,其值为<option>标签的value属性。若用户没有选择又没有用default属性指定默认值,则手机将改变量赋值为空字符串(""),对于多项选择,每个值用“;”分开。
  • default属性,可为name属性指定的变量赋成默认值。
  • iname属性,用来记录用户选择项的位置,相应的值从1开始。若没选,则该值为0
  • ivalue属性,用来记录默认值所在的位置。

    <optgroup>可用来将多个<option>分组,<optgroup></optgroup>间还可包括<optgroup><option>,该标签目前尚未被支持。
    <option>,类似于HTML中选单的<option>,用来表示选单的可选项。<option></option>间可包括事件和选单的显示文本。<option>的属性为可选,其中value属性用来提供值。当选到该项后,将该值赋给<select>name属性所指定的变量。onpick属性,用来指定用户选到该项并按ACCEPT键后所打开页面的URL

    为了说明选择项的工作方式,请看下面的例子:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <card id="card0" ordered="false">
    <p>
        Please select a city...
        <select title="Cities List" name="city">
            <option title="Beijing" value="c1">Beijing</option>
            <option title="Shanghai" value="c2">Shanghai</option>
            <option title="Hongkong" value="c3">Hongkong</option>
        </select>
        Please select columns...
        <select title="Column List" multiple="true" name="col">
            <option title="Hot News" value="l1">News</option>
            <option title="Cool Sports" value="l2">Sports</option>
            <option title="Pop Enter,,," value="l3">Entertainment</option>
        </select>
    </p>
</card>
</wml>

    使用Nokia WAP Toolkit对该程序进行测试。启动Nokia WAP Toolkit,并选择“Go”下的“Open Location”。在输入URL地址后,可以看到模拟器上出现如图3-14所示。


3-14 首页

    3-15所示是单选框的样子:


3-15 单项选择

    3-16所示的是多项选择框的样子:


3-16 多项选择

    3-17所示的是在完成多项选择后的样子:


3-17 完成选择后

事件

    WML的事件基本上分为两大类,一类是键盘(包括软硬按钮)输入事件,用<do>标签来处理。另一类是相关页面内部的事件,用<onevent>标签来处理。
<do>的语法如下:

    <do type="type" label="label" name="name" optional="false|true">

    任务</do>,任务就是以前提到的四种任务。<do>的属性中,type是必选的,其他为可选。

  • label属性,指定了软按钮在屏幕上的显示文本。目前type属性为deletehelpprev时该属性无效。
  • name属性,为<do>取个名字。同一的卡片里的<do>不能重名。如果卡片级的<do>和页面级的<do>同名,则覆盖页面级的<do>
  • optional属性,指定手机是不是可以忽略这个事件,默认值是false
  • type属性,指定触发的事件,具体如表3-5所示:

3-5 type的枚举值

枚举值

触发原因

accept

调用ACCEPT按钮机制

delete

调用DELETE按钮机制

help

调用HELP按钮机制

options

调用选择按钮机制

prev

调用PREV按钮机制

reset

调用清除和重新设定手机状态时的RESET机制(目前不支持)

unknown

调用unknown机制。等价于type=""(目前不支持)

Vnd. co-type

调用厂商特定的机制(目前不支持)

X-*, x-*

供以后使用(不保留)(目前不支持)

    为了演示事件的触发过程,请看下面的例子:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <head>
        <meta http-equiv="Cache-Control" content="max-age=0"/>
    </head>
    <card id="card0" ordered="false">
        <do type="accept" label="InputName" name="do1">
            <go href="#card01"/>
        </do>
        <p>
            NAME:<input name="userName" title="User Name" type="text" format="*M" emptyok="false" maxlength="12"/>
        </p>
    </card>
    <card id="card01">
        <p>
            You name is $(userName:noesc).
        </p>
    </card>
</wml>

    使用Nokia WAP Toolkit对该程序进行测试。启动Nokia WAP Toolkit,并选择“Go”下的“Open Location”。在输入URL地址后,可以看到模拟器上出现图3-18所示的界面。

3-18 主界面

    在选择“Optionos”后出现了事件选择项(图3-19)。注意到“InputName”是do标签名字。

3-19 事件选项

    在选择了“InputName”事件后,模拟器上将出现图3-20所示的界面:

3-20 输出姓名

    <onevent>的语法如下:

        <onevent type="type">任务</onevent>

    必选属性type的取值如表3-6所示:

3-6 type属性的取值

枚举值

如果用户执行了以下操作就执行任务

onpick

用户选择或不选一个<option>项时

onenterforward

用户使用<go>任务到达一个卡片时

onenterbackward

用户使用<prev>任务返回到前面的卡片时,或者按BACK按钮时

ontimer

<timer>过期时

    请研究下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
    <head>
        <meta http-equiv="Cache-Control" content="max-age=0"/>
    </head>
    <card id="card0" ordered="false">
    <p>
        Please select a city...
        <select title="Cities List" name="city">
            <option title="Beijing" value="Beijing">
            <onevent type="onpick">
                <go href="#card01"/>
            </onevent>Beijing</option>
            <option title="Shanghai" value="Shanghai" onpick="#card01">Shanghai</option>
         <option title="Hongkong" value="Hongkong" onpick="#card01">Hongkong</option>
        </select>
    </p>
    </card>
    <card id="card01">
        <p>
            You are Living in $(city:noesc)
        </p>
    </card>
</wml> 

    <timer/>可以用作在用户不进行任何操作的一段时间后,自动执行一个任务,任何激活卡片页面的任务和用户操作都会启动<timer/>,而任务进行时,<timer/>就停止。每个卡片只能有一个<timer/>,一个<timer/>只能触发一个任务。语法如下:

        <timer name="variable" value="value"/>

    其中name为可选属性,指定为一个变量名。当退出该卡片时,该变量存储此时定时器的值。当定时器超时时,手机将该变量设为0value为必选属性,用来设置定时器的定时值,最小单位为0.1秒。
    请研究下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<head>
    <meta http-equiv="Cache-Control" content="max-age=0"/>
</head>
<card id="card1" ontimer="#card2">
    <timer name="time1" value="50"/>
    <p align="center">
    After 5s, goto card2
    </p>
</card>
<card id="card2">
    <onevent type="ontimer">
        <go href="#card1"/>
    </onevent>
    <timer name="time2" value="50"/>
    <p align="center">
        Here is card2!
    </p>
</card>
</wml> 

    再提一下:<onevent><timer><do>三者必须按以上顺序写。
    此外在页面级还可以加入<template>,用来将事件捆绑在页面级上,语法如下:

<template onenterforward="url" onenterbackward="url" ontimer="url">
    <do>或者<onevent>
</template>

    请研究下面的例子程序:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<head>
    <meta http-equiv="Cache-Control" content="max-age=0"/>
</head>
<template>
    <do type="accept" label="deckPress" name="do1">
    <go href="#card01"/>
    </do>
</template>
<card id="card0" ordered="false">
    <do type="accept" label="cardPress" name="do1">
        <go href="#card02"/>
    </do>
    <p>
        Press ACCEPT...
    </p>
</card>
<card id="card01">
    <p>
        Here is card01
    </p>
</card>
<card id="card02">
    <p>
        Here is card02
    </p>
</card>
</wml>

四、编程指导

以下将要简明扼要地讲述WML标记的特点以及使用方法。并指导初学者学习和熟悉WML语言。在对WML有初步了解的基础上,下面将要讲述的是WML语法中的重点部分。了解这些部分就等于对WML有了一个比较全面的了解。

1. WAP构架

    • WML是一种适用于无线互连网的标记语言。
    • WAPWireless Application Protocol)是适用于无线互连网的网络协议。
    • 客户是各种基于WAP协议的手持设备或者是各种模拟器。
    • WAP网关有两个功能:对WML网页进行编码和解码;实现HTTP协议和WAP协议之间的转换,如图3-21所示。
    • WAP服务器是指在MIME配置中设置了WML数据类型的Web服务器。
    • 为什么采用WAP:方便、安全。

3-21 WAP构架


2. URL

    • WML使用和HTML相同的引用方式。

        例如:http://wap.yestock.com/index.wml

    • URL后使用片段。

        例如:http://wap.yestock.com/index.wml#login

    • 相对的URL——基础URL是当前的卡片。

        例如:<go href="/next" />


3. Content-type

    • 在互联网上使用WML数据类型。
    • 要想使用Web服务器传输WML数据类型,就需要对Web服务器的MIME设置进行配置。
    • 需要增加以下数据类型:

wmltext/vnd.wap.wml
wmlcapplication/vnd.wap.wmlc
wmlstext/vnd.wap.wmlscript
wbmpimage/vnd.wap.wbmp
其他可选的数据类型:
wmlscapplication/vnd.wap.wmlscriptc
wmlscripttext/vnd.wap.wmlscript
wstext/vnd.wap.wmlscript
wscapplication/vnd.wap.wmlscriptc


4. WML字符集

    • WMLXML的子集,继承了XML的字符集设置。
    • WML文档默认的字符集是UTF–8

5. 标签和属性

    • 标签:

    一个完整的WML标记有以下两种格式:

        1<tag> content </tag>
        2<tag/>

    • 属性:
      • 可以随意地指定或添加标签的属性。
      • 属性的格式:<tag attr="abcd"/>
      • 所有的XML名字都是大小写敏感的。
      • 所有的属性值都必须用双引号或单引号括起来。

6. 变量

    • WML卡片中可以使用变量。
    • 描述变量的语法在WML中有最高的解释优先级。
    • 当空格无法表示一个变量名结束的时候,就必须使用括号将参数名括起来。
    • $$WML中代表一个‘$’符号。
    • 变量语法格式有以下三种:
      • $identifier
      • $(identifier)
      • $(identifier:conversion)
    • 变量使用说明:
      • 可以在字符串中使用。
      • 可以在运行中更新变量的值。
      • 如果变量不等同于空字符串,变量处于设置状态(NOT NULL)。
      • 如果变量等同于空字符串,变量处于未设置状态(NULL)。
    • 变量替代:
      • 变量的数值可以代入卡片中的文本。
      • 只有文本部分可以实现替代。
      • 任何标签和属性都不能使用变量来替代。
      • 替代将在运行期发生。
      • 替代将不影响变量现在的值。
      • 替代是按照字符串替代的方式工作。
      • 如果一个没有定义的变量要实现替代,那么该变量将被看作空字符串。
      • 变量名是由US-ASCII码、下划线和数字组成,并且只能以US-ASCII码开头。
    • 变量名是大小写敏感的。

7. 美元符号

    • 美元符号:
      • 要想在文本中显示美元符号,必须成对使用。
      • 一个美元符号表示变量替代。
      • 一个简单的显示美元符号的例子:This is a $$ character
    • 有效性:
      • 在美元符号后面接字符串都将被认为是变量替代或者是生效。
      • 几个无效的例子:

                <!--错误的变量语法-->
                Balance left is $10.00.
                <!--错误的位置(变量type在属性内)-->
                <do type="x-$(type)" label="$type">


8. newcontext属性

    newcontext等于truefalse,将决定浏览是否做以下事情:

    • 删除所有在当前上下文中定义的变量。
    • 清除历史信息。
    • 重新设置所有的状态为一个默认的状态。

        例如:<card id="card1" title="Mortgage Calc" newcontext="true">


9. 大小写敏感

    • WMLXML都是大小写敏感的语言。
    • 所有的WML标记和属性都是小写敏感的。
    • 任何枚举的属性值也是大小写敏感的。

10. 页面与卡片

    • WMLXML语言的子集。
    • 一个WML应用是由许多页面(deck)所组成的。一个WML的页面就相当于HTML的一页。
    • 一个WML页面是由文件声明和WML标记对组成。
    • WML标记对中间有一个或多个卡片组成。
    • WML就是在各个卡片之间传递信息和切换。

11. WML标记对

WML标记对是指<wml></wml>组成的标记对。

    • WML标记对是任何一个WML页面的根标签。
    • WML标记对中可以包含一个或多个卡片。
    • WML标记对中可以使用可选的模板来生成所包含的所有卡片的相关动作。

12. WML例子

先阅读下面的例子,在后面对例子中的各个部分将做详细的解释。

<?xml version="1.0"?>
<!DOCTYPE WML PUBLIC "-//WAPFORUM//DTD WML1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">

<wml>
  <card>
    <p>
     Hello world !
     This is the first card
    </p>
     <do type="accept">
        <go href="#card2"/>
     </do>
  </card>
  <card id="card2">
    <p>
     This is the second card.
     Goodbye
    </p>
  </card>
</wml>


13. 文件声明

    • XML声明总是在文件的第一行。前面最好不要有空格或者换行。

<?xml version="1.0"?>

    • DOCTYPE声明。

<!DOCTYPE WML PUBLIC "-//WAPFORUM//DTD WML1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">


14. 事件与导航

    • WML包括导航和事件处理模块。
    • WML允许作者指定需要处理的事件。
    • 事件可以和所需要完成的任务捆绑在一起。
    • URL导航就是这样的一个例子。
    • 事件捆绑是通过几种标签声明来完成的,包括:godoonevent
    • do标签比go标签需要用户更多的参与。

15. do标签

    • do标签提供了一个通用的事件处理机制,使得用户可以参与当前卡片的事件处理。
    • WML提供一些预先定义的do模块。
    • accept:确定(或接受)。
    • prev:返回到上次的位置。
    • help:请求帮助。
    • options:上下文敏感的选项请求。

<do type="options" name="do1" label="options">
   <go href="/options"/>
</do>


16. 任务

    • go标签——当用户选中该标签时,就引导用户去WML中指定URL

<go href="http://www.simpleteam.com/wireless.wml">Simple Team</go>

    • prev标签——当用户选中该标签时,就引导用户去上次用户访问过的URL

<do type="options" name="do1" label="default">
  </prev>
</do>

    • refresh标签——当用户选中该标签时,变量值将被重新设置。

<do type="refresh">
  <refresh>
    <setvar name="firstname" value="forest">
    <setvar name="lastname" value="luo">
    <setvar name="age" value="25">
  </refresh>
</do>


17. setvar标签

    • 指定在当前上下文中的变量值,从侧面影响正在运行的任务。
    • 必须使用name属性指定变量的名字。
    • 必须使用value属性指定所要赋给变量的值。

18. selectoption标签

    • select标签和option标签是用来在WML中形成选择任务。
    • option标签可以指定在用户做出选择后的目标地址。

<select name="type">
  <option value="boxed" onpick="#selectBoxed">boxed</option>
  <option value="arranged" onpick="selectArranged">arranged</option>
</select>


19. input标签

    • input标签是用来收集用户的输入。

1.          name属性是用来指定变量的名字。

2.          value属性可以指定变量默认的值。

<input name="firstname" type="text" value="Robert" format="*A" maxlength="32"/>
<input type="text" name="age" format="*N"/>
<input type="text" name="address" format="*M"/>
<input type="password" name="password"/>

64.     type属性可以用来指定按密码输入模式进行输入,否则就是普通的文本输入模式。

65.     format属性用来指定输入的内容是数字(N)、字母、字母和数字,输入长度,大写或者小写等等。


20. 文本类标签

66.     段落:<p></p>(自动换行模式切换)

67.     空白:空格、制表符和换行都将被显示为空白。

68.     重点:em(强调)、strong(特别强调)、i(斜体)、u(下划线)、big(预定义的大字体),small(预定义的小字体)。

69.     br标签:建立新的一行。

<p>
  <b>
     Welcome to
  </b>
  <strong><i>
     Simple Team
  </i></strong>
  <u>
    WAP site
  </u>
</p>


21. 超链接标签

70.     a标签和anchor标签被用来创建一个超级链接。选中该标签的时候,用户将被带入到链接的地址(可以是另外的页面或者是同一页面下的不同卡片)。

71.     也可以不使用a标签和anchor标签,而采用go标签中的href属性来创建一个超级链接。

<anchor>
  fullow me<go href="destination"/>
</anchor>

<a href="destination">fullow me</a>

<do type="accept" label="ACCEPT">
  <go href="http://www.simpleteam.com/yourcode" method="post">
    <postfield name="w" value="12"/>
    <postfield name="password" value="your password"/>
  </go>
</do>


22. timer标签

72.     timer可以用来延时显示页面或卡片,或在页面和卡片间实现切换以取得动画效果。

73.     下面的例子就是在显示“Hello World”5秒钟后,用户将被自动引导至"/next"所指定的位置:

<wml>
  <card ontimer="/next">
    <timer value="50"/>
    <p>
      Hello World !
    </p>
  </card>
</wml>


23. 注释

74.     简单的注释(单行或多行,注释中没有WML标记)。

<!—将注释写在这里-->

75.     使用CDATA标记来实现带有WML标记的注释。

<![CDATA[很多内容
  <b>buld text</b>
  ……
  <table culumn="2">
 
  </table>
  还有很多…
]]>


24. template标签

template标签声明一个在页面中所有卡片都可以使用的事件处理模块。

76.     模块中的事件处理将自动应用于同一页面中的所有卡片。

77.     某个卡片可以通过定义同名的事件处理来替代模块中的事件处理。

<wml>
  <template>
    <do type="options" name="do1" label="default">
      <prev/>
    </do>
  </template>
  <card id="first">
  <!—该卡片将自动套用模块中定义的事件处理过程-->
 
  </card>
  <card id="second">
  <!—该卡片将使用空操作(noop)来替代模块中定义的事件处理过程,那么就等价于该卡片中没有该事件处理过程—>
    <do type="options" name="do1">
      <noop/>
    </do>
   
  </card>
  <card id="third">
  <!—该卡片使用同名的事件处理替代模块中提供的事件处理—>
    <do type="options" name="do1" label="options>
      <go href="/options"/>
    </do>
  </card>
</wml>


25. table标签

78.     table标签是用来创建能容纳文本和图片的表格。

align属性是用来指定对齐的方式(“L”是左对齐,“C”是对中,“R”是右对齐。默认的对齐方式是从左到右的左对齐方式)。

79.     tr标签用来指定表格的行。

80.     td标签用来指定表格的列。

<table culumns="2">
  <tr><td>One</td><td>Two</td></tr>
  <tr><td>1</td><td>2</td></tr>
  <tr><td>BA</td><td>B</td></tr>
</table>


26. img标签

81.     当设备不能显示图像的时候,alt属性指定可选的文本。有时候这个属性是必须的。

82.     src属性指定图像的来源。

83.     align属性指定图像与相邻的文本对齐方式。

<p>
<img alt=":)" src="http://www.simpleteam.com/logo.gif"/><br/>
Welcome to
</p>


27. postfield标签

指定向服务器指定提交时候的参数名字和参数数值。

84.     LoginPassword校验是最常用提交。

85.     一个使用go标签的提交例子。

<go href="http://193.120.145.194:80/wap" methos="post">
  <postfield name="LI" value="$LI"/>
  <postfiels name="PV" value="$PV"/>
</go>


28. 事件

86.     ontimer事件:该事件发生在定时器过期的时候。

87.     onenterforward事件:该事件发生在用户选中一个有效的URL之后,在正式引导用户去该URL地址之前。

88.     onenterbackward事件:该时间发生在用户选中一个有效的prev操作之后,在正式引导用户之前。

89.     onpick事件:该事件发生在用户选中某个选项。

<card>
  <onevent type="onenterforward">
    <go href="/url_to_check_security"/>
  </onevent>
  <p>
    Help
  </p>
</card>
<card onenterforward="/url_to_check_security"/>
  <p>
    Hello
  </p>
</card>


29. WML核心数据

90.     长度:

§         可以用整数指定画布(屏幕、纸张)的像素大小,或者用百分数表示占用的长度或宽度。

§         “50”表示50个像素。

§         “50%”表示占用一半的位置。

§         只能用在属性值中。


30. idclass属性

91.     所有的WML标签有两个核心属性:idclass

92.     这两个属性被用于服务器方的信息传输。

93.     id提供某个标签在页面中唯一的名字。

94.     class接收标签一个更多的class定义。

95.     多个标签可以使用同一个class定义。

96.     class的名字是大小写敏感的。

97.     标签也可以作为class中的一个部分。


31. 编程指导

尽量使用户的操作简单、友好。

98.     建立一个操作流程图。

99.     定义每个卡片的操作。

100. 保持每个卡片小而且简单。

101. 尽量减少按键的次数。

102. 不要使用WML所有的属性(各个厂家对WML兼容情况是不同的)。


32. 创建一个新的WML文件

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/WML_1.1.xml">
<wml>
  <card id="card_name" title="title_name">
    <!write your code here-->
  </card>
</wml>

由于WML的格式基本上都是一样的,可以自己做一个模板。这样省去了反复录入页面开头和结尾的时间。如果使用的是MADK或者Nokia WAP Toolkit,那么在每次新生成WML文件的时候,它会自动地将模板准备好。在以后的程序中,为了说明的简洁,WML的标准开头和结尾将被省略。只要主要的卡片。


33. 增加卡片

103. 根据自己的需要改变卡片的idtitle

104. 增加卡片的内容。

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card id="welcome" title="welcome">
  <p>
      MADK WML DEMO.
  </p>
</card>
</wml>


34. 增加动作

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1 //EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card id="welcome" title="welcome">
    <do type="accept">
      <go href="#greeting"/>
    </do>
    <p>
      MADK WML DEMO.
    </p>
  </card>
  <card id="greeting">
    <p>
      Welcome to the wireless bookshop.
    </p>
  </card>
</wml>

    下面将程序在Nokia WAP Toolkit上进行测试。启动Nokia WAP Toolkit,在“Go”下选择“Open Location”。在输入URL地址后,模拟器上出现图3-22所示的界面:

 3-22 欢迎界面

    这个时候显示的是页面中的第一张卡片。也就是id为“welcome”的card。它的标题是“welcome”。在选择“Options”后(这是Nokia的选择习惯,不同的模拟器的操作有所不同),模拟器上出现图3-23所示的界面:

3-23 选择菜单

    在选择“Select”之后,模拟器上出现图3-24所示的界面。这是同一个页面中的第二张卡片。该卡片的id为“greeting”。由于没有设置title参数,因此模拟器没有显示标题。

3-24 第二张卡片


35. 建立一个动画消息

<card id="greeting" ontimer="#card2" title="Toulkit Demo">
  <timer value="30"/>
  <p>
    <big>
      Welcome to
    </big>
  </p>
</card>
<card id="card2" ontimer="#card3" title="Toulkit Demo">
  <timer value="30"/>
  <p>
    <b>
      the Wonderful
    </b>
    <u>
      Wireless
    </u>
  </p>
</card>
<card id="card3" title="Toulkit Demo">
  <p>
    <big><i>
      Bookstore.
    </i></big>
  </p>
</card>

    Nokia WAP Toolkit对该程序进行测试。启动Nokia WAP Toolkit,在“Go”下选择“Open Location”。在输入URL地址后,模拟器上出现图3-25所示的界面。等待3秒,将跳到下一张卡片如图3-26所示。注意value30,其实要除上10才是以秒为单位。

3-25 欢迎界面

    Nokia WAP Toolkit<big><u>支持得还挺好!等待3秒,将跳到下一张卡片。

3-26 第二张卡片

    <i>的支持也不错!已经到了最后一个页面(图3-27),不会再跳动了。如果想实现反复地跳动,可以试试自己修改一下程序。如果在程序中加入了另外的事件处理,那么当用户触发这些事件的时候,动画就会停止。

3-27 最后一张卡片


36. 建立选项列表

<card id="card3" title="Toulkit Demo">
  <do type="accept">
    <go href="#cullectBookType"/>
  </do>
  <p>
    <b><i>
      BookStore.
    </i></b>
  </p>
</card>
<card id="cullectBookType">
  <p>
    Science or novel:
    <select name="type">
      <option value="science" onpick="#science">Science</option>
      <option value="novel" onpick="#novel">novel</option>
    </select>
  </p>
</card>

    Nokia WAP Toolkit对该程序进行测试。启动Nokia WAP Toolkit,在“Go”下选择“Open Location”。在输入URL地址后,模拟器上出现图3-28所示的界面。

3-28 欢迎页面

 

    在进入到“Options”后,模拟器上出现图3-29所示的界面:

3-29 选择菜单

   在选择“OK”以后,模拟器上显示的就是Nokia WAP Toolkit的选择方式(图3-30)。必须选择“Options”才能进入选择状态。目前默认的是“Science”。

 3-30 可编辑的选择项目

    在选择“Options”之后出现了浏览选项菜单(图3-31)。当然只有“Edit Selection”这一个选项。

3-31 选择编辑选项

    在出现了所有的可选择项目(图3-32)。默认的状态是“Science”。注意,选择“Select”和”OK”两个操作所产生的结果是不一样的。

3-32 所有的可选择项目

    选择“Select”之后,就立即触发了“onpick”事件。显然没有找到novel这张卡片。Nokia WAP Toolkit抛出了一个错误警告!(图3-33

3-33 错误警告

    果选择了“OK”,那么就回到了开始的选择页面。但是默认的选择变成了“novel”,说明修改成功(图3-34)。这两个操作方式的区别在于:前者主要是用来导航,而后者将修改选择值,type这个时候应该等于“novel”。

3-34 修改成功


37. 建立更多的选项

<card id="science">
  <p>
    select science title:
    <select name="productID">
      <option value="universe" onpick="#price">The Universe</option>

      <option value="space" onpick="#price">Facts About Space
      <option value="time" onpick="#price">Time Machine
    </select>
  </p>
</card>
<card id="novel">
  <p>
    select novel title:
    <select name="title">
      <option value="speed" onpick="#price">Speed</option>
      <option value="terminator" onpick="#price">Terminator</option>
      <option value="ghost" onpick="#price">Ghost</option>
    </select>
  </p>
</card>

    如果把上面的程序加入到3.4.36的程序中,那么在选择“Select”的时候,就不会抛出错误警告了。读者可以自己再试试。


38. 滚动和setvar

<card id="price">
  <do type="accept">
    <go href="#copies>
      <setvar name="price" value="30.0"/>
      <setvar name="discount" value="0.00"/>
    </go>
  </do>
  <p>
    Click accept to find the
    Price and enter number of copies you need:
  </p>
</card>


39. 使用input

105. 使用正确的格式。

106. 选择一个合适的标题。

107. 限制所输入内容的最大长度。

108. 收集名字

<card id="collectName">
  <do type="accept">
    <go href="#collectAddress"/>
  </do>
  <p>
    name:
    <input name="fullName" title="Full Name" format="*A" maxlength="9"/>
  </p>
</card>

109. 收集地址

<card id="collectAddress>
  <do type="accept">
    <go href="#cardType">
      <setvar name="ship" value="4.0"/>
    </go>
  </do>
  <p>
    address:
    <input name="address" title="Address" format="*M" maxlength="9"/>
  </p>
</card>


40. 选择信用卡类型

<card id="cardType">
  <p>
    what kind of credit card?
    <select name="creditCardType">
      <option value="visa" onpick="#cardNo">visa
      <option value="mastercard" onpick="#cardNo">mastercard</option>
      <option value="discover" onpick="#cardNo">dicover</option>
    </select>
 </p>
</card>


41. 输入信用卡号码

<card id="cardNo">
  <do type="accept">
    <go href="#cardDate"/>
  </do>
  <p>
    card number
    <input name="cardNumber" title="Card Number" format="*N" maxlength="16"/>
  </p>
</card>


42. 输入信用卡过期日期

<card id="cardDate">
  <do type="accept">
    <go href="#confirmation"/>
  </do>
  <p>
    expiration date
    <input name="creditCardExp" title="Expiration Date" format="*N" maxlength="8"/>
  </p>
</card>


43. 确认

<card id="confirmation">
  <p>
    Each is $$ $(price), you ordered $(unint) copies,
    Shipping is $$ $(ship), and total is $$64,
    Thank you ! Bye Bye !
  </p>
</card>


44. 卡片调用

<card id="collectAddress">
  <do tyoe="accept">
    <go href="card.wml#cardType">
      <setvar name="ship" value="4.0"/>
    </go>
  </do>
  <p>
    address:
    <input name="address" title="Address" format="*M"/>
  </p>
</card>


45. 复合调用

<card id="collectAddress">
  <do type="accept">
    <go href="http://www.abc.com/wml/card.wml#cardType">
      <setvar name="ship" value="4.0"/>
    </go>
  </do>
  <p>
    address:
    <input name="address" title="Address" format="*M"/>
  </p>
</card>


46. 调用WMLScript

<card id="confirmation">
  <do type="accept" label="Calculate">
    <go href="calculateTotal.wmls#calculateTotal($(price),$(unit),$(ship))"/>
  </do>
  <p>
    Each is $$ $(price),
    You ordered $(unit) copies,
    Shipping is $$ $(ship), and
    Total is $$ $(total)
  </p>
</card>


47. WMLScript例子

//wml script used by book store application
extern function calculateTotal(a,b,c)
{
//a: unit price
//b: number of units
//c: shipping charges

  var total=a*b+c;
  WMLBrowser.setVar("total",total);
  WMLBrowser.refresh();
}

五、WML标记

   这个部分详细地说明了WML语言中各个标记的语法和使用方法。每个标记都有一个简单的例子供参考。

1. <a>

    这是短格式的锚语法。使用<a>代替<anchor>,并且只用来定义隐含的、指定了URL<go>任务。

语法

<a href="url" <!-- required --> title="label">
...any valid combination of <text>, <br/> and <img> elements
</a>

2. <anchor>

    <anchor>标签将一个格式化的文本和一个任务捆绑在一起。经常被称作超级链接,可以使用任何的文本或图标指定超级链接。当用户选择了超级链接,并且按下ACCEPT,设备就会执行该任务。

语法

<anchor title="label">task text</anchor> 

    task表示当用户激活超级链接以后所要执行的动作。text是设备显示在屏幕上,用来代表超级链接的文本。
    task
必须指定下列任务中的一个:<go><prev><refresh>
    text
设备通常将这段文字与其他的文字区别开。例如使用方括号,或者使用下划线。
    title用来标识link的标签。如果不指定title属性,设备将使用“link”作为默认的属性。设备可以以不同的方式使用这个标签。例如,在用户选择的时候可以用来显示一个帮助工具条,或者一个语音提示。为了兼容所有的设备,label最好不要超过5个字符。

例子:

<wml>
    <card>
        <p>
            Some links:<br/>
            <a title="Link1"><go href="d1.wml"/>News</a><br/>
            <a title="Link2"><go href="d2.wml"/>Sports</a>
        </p>
    </card>
</wml>

3. <access>

    <access>标签用来指定WML页面的操作权限。必须在head内和其他的meta信息一起声明。每个页面只有一个<access>标签。所有WML默认的权限是public

语法

<head>
    <access domain="domain" path="path"/>
    ...
</head> 

access的属性包括:

  • domain可对WML页面进行操作的URL域。默认的是当前页面所在的域。
  • path可对WML页面进行操作的其他页面所在的根目录。默认的是“/”(当前页面所在的根目录)这就使得所有的在domain域下的页面都可以操作该页面。

4. <b>

<b>指定黑色字体文本。

语法

<b>text</b> 

    text是需要使用黑体显示的文本。

例子:

<wml>
    <card>
        <p>
            Press <b>OK</b> to go to the next screen.
        </p>
    </card>
</wml>

5. <big>

    <big>指定大字体的文本

语法

<big>text</big> 

    text是所需要以大字体显示的文本。

6. <br/>

    <br/>标签用来指定换行。它将使得设备在新行上显示文本的图标。

语法

<br/> 

    注意:不像HTML所有的WML标签需要一个结尾标志“/”,因此在WML中插入一个新行是<br/>,而不是<br>

7. <card>

    一个WML页面是由一个或多个卡片(card)组成。每个卡片都包含了一套用户和设备交互的操作。设备每次只能显示一个卡片——有些情况下会显示一系列的卡片。

语法

<wml>
<card id="name" title="label" newcontext="boolean"
ordered="true" onenterforward="url" onenterbackward="url"
ontimer="url">
    content
</card>
</wml> 

    content代表了所有WML卡片的定义和操作的一系列内容:一个timer元素(或者没有)、一个或多个onevent元素、一个或多个do元素、pre元素等一系列的导航信息,此外一个card元素还可以包含一个或多个p元素。
    重点:<card>必须遵循以下顺序:<onevent><timer> <do>
    除了以上列出的,设备将按照所指定的顺序显示元素。

card的属性包括:

  • id指定card的名字。

    名字是导航时候的依据,例如,可以指定<go href="#cardname"/>来导航(参考<go>)。

  • title为卡片指定一个简短的标题。

    各种设备对此有不同的用途。
    注意: 生产厂家将会显示title,如果那儿有比较充分的屏幕空间。title属性应该看作是对用户的一种提示,而不是卡片所显示的内容。

  • newcontextBoolean类型)

    取值为true或者false,默认为false。当用户重新进入的时候 指定设备是否需要初始化卡片中所有的内容。当指定newcontext="true"那么所有的内容重新初始化,并清除历史记录。

  • orderedBoolean类型)

    取值为true或者false,默认为true。它指定卡片内容的组织形式。ordered="true"将使得设备按固定的顺序显示内容。否则根据用户选择的顺序来显示内容。
    ordered属性可以指定设备在一个卡片中显示多个内容时候的顺序。true 将按线型方式显示(默认的值)。使用这个设置时,将只显示必须的属性。如果设备无法在一屏上显示所有的内容,那么它将分屏显示:

    • 指定了field组,有一个或多个<fieldset>(参见<fieldset>)。
    • 无效的fields(使用了文本前缀作为每个部分的提示)。

    false允许用户在各个部分之间进行任意的导航。使用这个设置,可以不必考虑他们之间的顺序。如果设备不能将所有的部分显示在屏幕上,那么它将会出现一个可供选择的卡片,用户可以导航到每一个部分(根据自己的意愿进行选择或者输入一个选择值)。

  • onenterforwordhref类型)

    如果用户执行<go>,那么就打开指定的URL地址。这个属性是<onevent>的一个简短格式。

  • onenterbackwordhref类型)

    如果用户执行<prev>,那么就打开指定的URL地址。这个属性是<onevent>的一个简短格式。

  • ontimerhref类型)

    timer过期的时候,就打开指定的URL。这个属性是<onevent>的一个简短格式。

例子:

<wml>
<card>
    <do type="accept">
        <go href="#card2"/>
    </do>
  <p>
    Press OK to display the next screen.
  </p>
</card>

<card id="card2">
 <p>
    This screen displays the content of Card 2.
 </p>
</card>
</wml>

8. <do>

    <do>将用户的交互(例如功能键、声音提示等)和一个任务联系在一起。当用户激活这些功能的时候,设备就执行和<do>相联系的任务。
    重点:<do>已经扩展了功能:可以使用图标来作为label。这个功能可以通过嵌入<img>来指定。

例如:

<do type="accept">
   <go href="/foo"/>
   <img src="img" localsrc="OK" alt="OK"/>
</do> 

    如果手机支持imglocalsrcsrcalt,就应该保持这种顺序。如果不支持,就由alt指定label。如果指定了<img>,那么<do>中的label就被忽略。如果没有指定<img>,那么<do>中的<label>就被使用。

语法

<do type="type" label="label" name="name" optional="boolean">
    task
</do> 

task代表将要执行的动作:

do元素必须绑定goprevnooprefresh任务中的一个任务。

do的属性包括:

  • type

    绑定特殊的用户交互事件
    可以指定以下的type属性:

    • accept激活ACCEPT(功能键,按钮等等)。
    • delete激活DELETE(功能键,按钮等等)。
    • help激活HELP(功能键,按钮等等)。
    • options激活OPTIONS(功能键,按钮等等)。 
    • prev通过激活PREV导航到另外一个卡片。
    • reset激活RESET(清除和重设当前的状态)。
    • unknown激活未知道的机制(相当于TYPE="")。
    • X-*, x-*  将来用(没有保留)。
    • vnd.co-type 激活供应商的一个特定的功能。

    如果type 隐含了特殊的用户交互机制。有些设备将功能映射成按键,有些则映射成上下文独立的操作。因此当设计用户交互的时候,要记住不能指定设备将要使用的特别操作机制。
    注意: 如果在一个<card>中定义了多个<do>拥有同样的type,那么必须为每个<do>指定不同的name

  • label

    label可以标识用户的交互事件。例如,如果将一个任务绑定在ACCEPT键上,那么设备就会将label的值显示在屏幕上,如果不指定,那么默认显示"OK"。为了保证屏幕有足够的宽度,label最多不超过5个字符。如果不支持动态的标签,设备将忽略label属性。

  • name

    指定<do>的名字。如果卡片级别<do>(定义在<card>中)和页面级别<do>(定义在<template>中)具有同样的名字,卡片级别将将覆盖页面级别。

  • optional

    取值为true或者false,缺省为false。指定设备是否忽略这个标签。

9. <em>

    <em>指定强调文本。

语法

<em>text</em> 

    text是需要强调的文本。

10. <fieldset>

    <fieldset>允许在一个card中,定义一组text或者输入。指定一个或多个<fieldset>可以控制设备如何显示卡片的内容,用来简化用户的输入。

语法

<fieldset title="label">content</fieldset> 

    content表示以下内容中的一个或者多个的组合:control在一个<fieldset>组中,可以指定fieldsetinputselect的内容;text也可以在<fieldset> 组中指定格式化的文本。设备对这些文本的使用是大不一样的。例如:作为用户输入的提示,或者描述选项。
    <fieldset>的属性:title指定<fieldset>组的标签。一些设备当显示<fieldset>组的时候将作为显示用的标签。其他的也许用作用户交互的提示。

11. <go>

    <go>是一个任务标签,它将指导用户去打开一个指定的URL。如果URL是一个指定的卡片,那么设备将显示那个卡片。如果URL是一个指定的页面,那么设备就显示那个页面的第一个卡片。

语法

<go href="url" sendreferer="boolean" method="method"
accept-charset="charset"
<postfield name="data" value="value"/>
    content
</go> 

    content代表了打开的时候用来设置变量,可以指定一个或更多的变量。
    重点:不象其他的WML标签,指定content是可选的。如果不指定content,那么必须使用<go attributes/>代替<go attributes>content</go>

<go>的属性包括:

  • href

将要打开的URL

  • sendreferer

    取值为true或者false,缺省为false。指定设备是否要将所发送请求的页面的URL包含在内。如果sendreferer="true" 那么设备就要发送 HTTP_REFERER 头参照请求页面的相对URL。如果将操作权限限制在可信任的设备,那么就可以指定这项为true

  • method

    取值为get或者post,缺省为get。指定HTTP的提交方式。指定method="post" 将使得服务器将通过HTTP的头来传递变量。当变量值中有非ASCII字符,可以使用这种方式。如果不指定,那么默认地使用post方式。

  • accept-charset

    指定字符的编码方式。设备将使用这个属性来确定postfield元素传输的编码。一般来说服务器采用UTF-8作为默认的编码。

    注意:accept-charset属性将覆盖HTTP头中的任何的字符编码设置。语法格式为, accept-charset="UTF-8, US-ASCII, ISO-8859-1"
    以下的例子解释了<go>的使用方法:

<wml>
<card title="Employee" ordered="true">
    <do type="ACCEPT" label="Find">
        <go method="post" href="?next=list"
          <postfield name="next" value="list&amp"/>
          <postfield name="L" value="$last&amp"/>
          <postfield name="F" value="$first"/>
         </go>
    </do>
    Partial First Name:
    <input title="First Name" name="first"/>
    Partial Last Name:
    <input title="Last Name" name="last"/>
</card>
</wml>

12. <head>

<head>指定整个页面的头,包括metadataaccess控制信息。

语法

<head>
     content
</head> 

    content代表的是deck-level的头信息,content可以指定仅有一个access或一个或多个meta的内容。下面的例子指定页面的最大过期时间。WML通过<meta>中定义来决定缓冲控制。

<wml>
<head>
    <meta http-equiv="Cache-Control" content="max-age=3600"     forua="true"/>
</head>

<card>
    ...
    ...
</card>

<card>
    ...
    ...
</card>
</wml>

13. <i>

<i>指定斜体字的文本。

语法

<i>text</i> 

    text是需要按斜体显示的文本。

例子:

<wml>
    <card>
        <p>
            <i>Red</i>, <i>blue</i>, and <i>yellow</i> are primary colors.
        </p>
    </card>
</wml>

14. <img>

    <img>指导设备在格式化的文本中如何去显示一个图片。注意:不是所有的设备都可以显示图片。
    注意:不能在<do>或者<option>内指定图片。也不能将图片作为一个功能键的标题或者选项。

语法

<img alt="text" src="url" localsrc="icon" align="alignment" height="n" width="n" vspace="n" hspace="n"/> 

    <img>包括以下属性:

  • alt

指定可选的文本,假如设备无法显示执行的图片。

  • src

图片的URL地址。如果指定了一个有效图标的localsrc,那么设备就会忽略这个属性。

  • localsrc

已经知道的图标名字。如果设备在ROM中找不到,那么它将从服务器上寻找。如果指定了一个有效的图标,那么将忽略src属性。

  • align

    取值为topmiddlebottom,缺省为bottom。指定图片的垂直对齐方式。

  • height

    指定图片的高度。

  • width

    指定图片的宽度。

  • vspace
  • hspace

例子:

<wml>
<card>
  <p>
    Here's a smiley:
  </p>
    <br/><img alt=":-)" localsrc="smileyface" src=""/>
</card>
</wml>

    注意 :一些localsrc在不同的矢量字体下有不同的显示。既然控制不了显示的大小,应该记住在不同的设备上图标的显示差别很小。

15. <input>

    <input>可以让用户输入文本或者变量。

语法

text
<input name="variable" title="label" type="type"
value="value" format="specifier"
emptyok="boolean" size="n" maxlength="n" tabindex="n"/>

    text代表了用来提示用户输入的文本或者图片。
    input包括以下属性:

  • name

    变量的名字,设备将用它来保存用户输入的数值。如果变量没有数值,那么设备就将它设为默认的初始状态,也就是空字符串("")。当设备显示<input> 时,变量的数值会出现在输入栏内。

  • title

    指定一个简短的输入标题。有些设备将其作为一个帮助提示,当显示输入栏的时候。其他的也许将其作为一个交互时使用的标签。

  • type

    取值为text或者password,缺省为text。指定设备如何显示用户输入的文本。指定 type="text" 使得文本可见;指定 type="password" 使得文本不可见(例如,使用*代替原文本)。注意password方式,不是指加密方式。不能指望它带来安全保障。

  • value

    该属性是确定默认的数值。

  • format

    指定用户输入的匹配模式。如果省略这个属性,那么默认的就是*M

    下面是指定格式化掩码的标签:

    • A表示任何大写的字符(不包括数字)。
    • a任何大写的字符(不包括数字)。
    • N任何数字(不包含字符)。
    • X任何数字和大写的字符(不能变为小写)。
    • x任何数字和小写的字符(不能变为大写)。
    • M任何数字和大写的字符,可以大小写切换。
    • m任何数字和小写的字符,可以大小写切换。

    为了限制用户输入的字符个数,可以指定输入字符的限制,只需要在格式前面加上数字。例如 format="3X" 让用户最多输入3个符号、数字和大写的字符。为了不限制用户的输入,可以通过在格式前面指定“*”。例如:format="*a"可以让用户输入任意多的内容。

  • emptyok

取值为true或者false,默认为false。指定用户是否可以空着离开哪个项。指定 emptyok="true" 表明那个项目是可选的。

  • size
  • maxlength

    指定输入框的最大输入长度。默认的是256

  • tabindex

例子:

<wml>
    <card>
    <p>
        First Name:
            <input name="fname" maxlength="15" /> <br/>
        Last Name:
            <input name="lname" maxlength="15" /> <br/>
        State:
            <input name="state" maxlength="2" emptyok="true"       value="CA" /> <br/>
        Zipcode:
            <input name="zipcode" maxlength="9" /> <br/>
        Password:
            <input name="password" maxlength="8" type="password" />
    </p>
</card>
</wml>

16. <meta>

    <meta>元素为WML页面提供各种信息。这个元素是在页面的头部指定有关页面操作控制的信息。
   注意:不是所有的设备都支持附加信息。

语法

<head>
    <meta http-equiv="Cache-Control" content="max-age=time"
    forua= true />
    ...
</head> 

meta的属性包括:

  • name

    必须指定name的属性:name="name" http-equiv="name"

  • content

    指定一个和property相关的数据值。

  • scheme
  • forua

    取值为true或者false,默认为true。指定信息是否要发往用户代理。如果为“false”,那么相关的meta信息必须清除然后再发往客户代理。如果为“true”,那么相关的meta信息就直接分发给客户代理。

17. <noop>

    <noop>是一个任务元素。它指导设备不做任何事情。这个元素在覆盖页面级别时十分有用。

语法

<noop/>

18. <onevent>

    <onevent>和状态转移与内建事件相关。当内建的事件发生,设备将指定一个与<onevent>相关的任务。

语法

<onevent type="type">task</onevent> 

    这里task代表当内部事件发生的时候要执行的动作,可以指定goprevrefreshnoop中的任何一个元素。
    type属性标识内建事件,激活指定的任务。如果一个卡片级别的事件和一个页面级别的时间具有同样的类型,那么卡片级别的绑定将覆盖页面级别的绑定。
    可以指定以下的类型值:

  • onpick 用户选择或者放弃选择一个选项。
  • onenterforward 用户执行<go>任务。
  • onenterbackward 用户执行<prev>任务,或者激活PREV机制。
  • ontimer 一个指定的<timer>过期。

19. <optgroup>

    <optgroup>允许在一个卡片中组织多个<option>(或者嵌套的<optgroup>)。创建选择组可以指定设备如何显示一个卡片的内容。

语法

<optgroup title="label">content</optgroup> 

    这里content代表一个或多个以下的内容,可以指定以下的元素:

  • <optgroup> (嵌套的<optgroup>
  • <option>  设备将按顺序显示所指定的内容。

    title属性指定一个简单的标签。有些设备要将这个标签做为标题来使用。有些设备可能作为导航来使用。

20. <option>

    <option><select>中指定一个特殊的选择项目。
    重点:<option>元素已经扩展了功能,允许在<option>文本中加入图片。

例如:

<option value="1">
    <img src="/img1" alt="Choice 1"/>
</option>

语法

<option title="label" value="value" onpick="url">
    content
</option>

    这里content代表设备将要显示的文本内容以及当用户选中之后所要执行的动作,event可以指定onevent元素, text显示代表选择的文本。
    <option>的属性包括:

  • title

    标识选择项的标记。为了保证和大多数的设备兼容,label应该最大不要超过5个字符。

  • value

    指定将要赋给<select>中指定变量的值。如果指定了一个参考变量,那么设备将先测试变量有效性,然后再设置变量。

  • onpick

    指定在用户选择或者放弃选择(如果使用了多选)的时候,将要打开的URL地址。这个是一个<onevent>的缩写。

例子:

<wml>
<card>
  <p>
    Please select your favorite color:
    <select name="color">
        <option value="1">red</option>
        <option value="2">blue</option>
        <option value="3">green</option>
        <option value="4">yellow</option>
    </select>
  </p>
</card>
</wml>

21. <p>

    指定一个具有特定对齐方式和换行方式的新段落。

语法

<p align="alignment" mode="wrapmode">
   content
</p> 

<p>的属性包括:

  • align

取值为leftright或者center。指定显示行的对齐方式。如果没有,那么将采用左对齐方式。

  • mode

    取值为wrap或者nowrap,缺省为wrap。指定文本的换行方式。如果指定为nowrap,设备将使用另外的机制来显示过长的行,例如:水平滚动。设备将会使用指定的换行模式直到下一个新的指定。换句话来说:如果指定了模式属性,那么设备将应用这种模式。如果没有指定模式,那么设备将使用最后一次所指定的模式。如果以前没有指定过,那么默认采用wrap模式。

22. <postfield>

    <postfield>定义了一个将要传送给HTTP 服务器的名字数值对。

语法

<postfield name="name" value="value"/>

<postfield>的属性包括:

  • name

表明域的名字标签。

  • value

指定的数值

23. <prev>

    <prev/>是一个任务元素。它指导设备从当前的堆栈中移走URL,并打开前一个URL。如果堆栈中没有内容,那么<prev>将没有任何效果。

语法

<prev>content</prev> 

    这里content代表在打开前一个URL时,所需要设置的变量值。可以在其中指定一个或多个变量:<setvar>
    注意:不像其他的WML元素,<prev>的内容是可选的。如果没有指定任何内容,那么就必须使用<prev/>

24. <refresh>

    <refresh>元素是一个任务元素。它指导设备刷新卡片中的变量。设备当然也将更新屏幕上的变量。

语法

<refresh>content</refresh> 

    这里content代表需要刷新的元素变量,必须指定至少一个变量:<setvar>
    注意:可以使用<refresh>标签来设置变量的值,但是不可能将它们设置为NULL

例子:

<wml>
<card title="Employee" ordered="true">
    <do type="ACCEPT" label="Find">
        <go method="post" url="?next=list">
        <postfield name="NEXT" value="list&amp"/>
        <postfield name="L" value="$last&amp"/>
        <postfield name="F" value="$first&amp"/>
        </go>
    </do>
    <do type="OPTIONS" label="Clear">
        <refresh>
            <setvar name="first" value=""/>
            <setvar name="last" value=""/>
        </refresh>
    </do>
    Partial First Name:
    <input title="First Name" name="first"/>
    Partial Last Name:
    <input title="Last Name" key="last"/>
</card>
</wml>

25. <select>

    <select>元素指定用户选择项列表。可以指定单选或者多选。

语法

text
<select title="label" multiple="boolean" name="variable"
default="default" iname="index_var" ivalue="default"
tabindex="n">
    content
</select> 

    这里text代表用来提醒用户输入的文本或者图像。content代表可供选择的列表。可以使用<optgroup><option>来定义content

26. <setvar>

    当设备执行<go><prev>或者<refresh>任务时,<setvar>指定变量的值。

语法

<setvar name="name" value="value"/> 

    setvar的属性:

  • name

    需要设置的变量名。如果找不到这个变量,设备将忽略这个<setvar>

  • value

    指定变量的值

27. <small>

    指定小尺寸的矢量字体的文本。

语法

<small>text</small> 

    这里text表示需要显示的小字体内容。

28. <strong>

    指定所需要特别强调的文本。

语法

<strong>text</strong> 

    这里text代表需要特别强调的文本。

29. <table>

    <table>允许指定一个行格式化的输出,可以控制整个表格的对齐方式,但不是每个单元格的对齐方式。WML表格和HTML表格很像,但是只有少量的功能。在定义表格的时候,必须声明行数,以及后面的内容。这些内容可以是空行或者列。

语法

<table title="name" align="left|right|center" columns="number of columns">
...row and data declarations
</table>

table的属性包括:

  • align

取值为leftrightcenter,默认为left。指定文本的对齐方式。如果没有指定,那么默认将采用左对齐方式。

  • title

    指定表格的标签。

  • columns

    指定每行的列数。指定为0是不允许的。

30. <td>

    <td>元素是一个用来装入格子内容的容器。表单的格子可以为空。用户代理必须处理由于使用图像或者链接所带来的多行数据单元格。

语法

<td>content</td>

    这里content代表了在表单格中的文本,或者是<img><anchor>元素。可以指定<img><anchor>任何一种元素。

31. <tr>

    <tr>是一个用来装入表单行的容器。这个表单行可以为空,换句话说,所有的格子都是空的。

语法

<tr>
  <td>content</td>
</tr> 

    这里content代表表单格子中的内容,可以是文本,或者是<img><anchor>

32. <template>

    一个WML页面可能包含一个<template>元素来定义页面级别的事件捆绑。这些事件特点将对页面内的所有卡片起作用,可以通过指定卡片的同名事件捆绑来覆盖某个事件捆绑。

语法

<wml>
<template onenterforward="url" onenterbackward="url"
ontimer="url">
    content
</template>
</wml> 

    这里content代表了当事件发生时的一般动作,可以指定<do> <onevent>的任何一种元素来定义。
      template元素包括以下属性:

  • onenterforward

    如果用户通过<go>任务来浏览一个卡片,那么打开指定的URL。这个属性是<onevent>的一个缩写。

  • onenterbackward

    如果用户通过<prev>任务来浏览一个卡片,那么打开指定的URL。这个属性是<onevent>的一个缩写。

  • ontimer

    如果用户通过<timer>过期,那么打开指定的URL。这个属性是<onevent>的一个缩写。

33. <timer>

    <timer>提供了在一段时间的交互之后,自动激发任务的功能。任何一种用户的动作都将激活定时器,执行任何任务都将停止定时器。只能在一个卡片中定义一个定时器。

语法

<timer name="variable" value="value"/> 

<timer>的属性包括:

  • name

    name变量用来保存定时器的值。如果变量没有指定初始值,设备将自动使用默认的指定值。如果用户退出卡片,那么这个变量将被设置为当前时间。如果在定时器过期以后,设备将这个变量设置为0

  • value

    指定变量的关键属性。必须以1/10秒为单位指定<timer>的值,例如,100等于10秒。将值设置为0将停止timer。如果name在定时器之前已经有了一个值,那么设备将忽略默认的属性。如果变量名还没有值,那么设备将使用指定的数值设置该值。

    以下的例子解释了怎么初始化和重新使用一个计数器。当用户访问该卡片的时候,设备都将重新设置定时器的数值。如果定时器没有数值,设备将设置定时器为5秒。当定时器过期以后,设备将自动设置时间。

<wml>
<card ontimer="#card2">
    <timer name="time" value="50"/>
  <p>
    Hello, Unwired World!
  </p>
</card>

<card id="card2">
    ...
    ...
</card>
</wml>

34. <u>

<u>指定带下划线的文本。

语法

<u>text</u>

    这里text是将要显示下划线的内容。

35. <wml>

    <wml>指定一个WML页面。

语法

<wml xml:lang="lang">
<card>
    content
</card>
</wml>

    这里content代表定义页面动作的WML元素。
    wml的属性“Xml:lang”指定WML文档的语言。所指定的语言属性将覆盖其他任何语言指定语句的功能。

例如:

<wml xml:lang="en-us">
<card>
    ...
    ...
</card>

六、WML速查

其中包括了所有的WML标签的语法速查

3-7中包括了所有的WML标签的语法速查。

3-7 WML速查

标记

语法

<wml>

<wml xml:lang="lang" >
   content
</wml> 

<card>

<card id="name"
      title="label"
      newcontext="boolean"
      style="style"
      onenterforward="url"
      onenterbackward="url"
      ontimer="url" >
   content
</card> 

<template>

<template onenterforward="url"
          onenterbackward="url"
          ontimer="url" >
   content
</template> 

<head>

<head>
   content
</head> 

<access>

<access domain="domain"
        path="path" /> 

<meta>

<meta name="name"|http-equiv="name"
      content="value"
      forua="true | false" /> 

<timer>

<timer name="variable"
       value="value" /> 

<setvar>

<setvar name="name"
     value="value" /> 

<anchor>

 

<a>

<a title="label" >
   task
   text
</a> 

<do>

<do type="type"
    label="label"
    name="name"
    optional="boolean" >
task
</do> 

<onevent>

<onevent type="type" >
   task
</onevent> 

<go>

<go href="url"
    sendreferer="boolean"
    method="method"
    accept-charset="charset"
content
</go> 

<prev>

<prev>
   content
</prev> 

<noop>

<noop/> 

<refresh>

<refresh>
   content
</refresh> 

<img>

<img alt="text"
     src="url"
     localsrc="icon"
     align="alignment"
     height="n"
     width="n"
     vspace="n"
     hspace="n" /> 

<input>

<input name="variable"
       title="label"
       type="type"
       value="value"
       default="default"
       format="specifier"
       emptyok="boolean"
       size="n"
       maxlength="n"
       tabindex="n" /> 

<select>

<select title="label"
        multiple="boolean"
        name="variable"
        default="default"
        iname="index_var"
        ivalue="default"
        tabindex="n" >
   content
</select> 

<option>

<option title="label"
        value="value"
        onpick="url" >
   content
</option> 

<optgroup>

<optgroup title="label" >
   content
</optgroup> 

<fieldset>

<fieldset title="label">
   content
</fieldset> 

<b>

<b>
   text
</b> 

<big>

<big>
   text
</big> 

<br>

<br/>

<em>

<em>
   text
</em> 

<i>

<i>
   text
</i> 

<p>

<p align="alignment"
    mode="wrapmode" /> 

<small>

<small>
   text
</small> 

<strong>

<strong>
   text
</strong> 

<table>

<table align="alignment"  
       title="label" 
       columns="n"/> 

<td>

<td>content</td> 

<tr>

<tr> 
  <td>content</td> 
</tr> 

<u>

<u>
   text
</u> 

 

七、字符实体

其中包括了WML中字符实体与其对应字符。

3-8中包括了WML中字符实体与其对应字符。

3-8 字符实体

字符实体

字符

&lt;

&gt;

&apos;

&quot;

&amp;

&

&nbsp;

空格

&shy;

-

 

八、WMLScript

WMLScript语言也是WAP应用层的组成部分之一。这种语言是基于ECMAScript语言的,但是它更适合于窄道通信。在应用时,WMLScript可以和WML文档一起,问客户端增加动态功能,此外WMLScript也可以作为一种独立的工具使用。

WMLScript是一种程序语言,它可以调用在本地安装的标准库函数。为了在传输时节省带宽,WMLScript程序先被编译成字节码(bytecode),传到客户端后,再通过解释器执行。这也是WMLScriptECMAScript的重要区别之一。

 

基本原则

总的来说,由于WMLScript是以C语言为蓝本制定的,因此其语法特征和C语言很相象。在学习的过程当中,可以参考C语言。

1. 大小写敏感

    WMLScript 1.1是一个大小写敏感的语言。所有的关键字、变量和函数名都必须合理地使用大小写。


2. 空格与换行

    WMLScript 1.1忽略所有程序间的空格、制表符、换行,字符串常量里面的空格、制表符、换行不被忽略。例如WMLScript能够识别以下几种字符串:

    • "June 29, 1908"
    • "June29,1908"
    • "6/29/08"

3. 注释

    WMLScript 1.1有两种注释结构:

    • 行注释:从使用“//”开始到这行结束都算做注释。
    • 块注释:以“/*”开始到“*/”结束。

    编译器不支持注释嵌套。


4. 直接编码

    有一些数值将直接编码并嵌入在程序之中。直接编码的内容如下:

·         整数

    按以下方式使用数字,就使用直接编码:

    • 十进制

        十进制的数字是不以0开头,只包含0~9的字符串。

        例如:-41

    • 十六进制

        十六进制是以0X或者0x开头,只包含0~9a-f或者A-F的字符串。

        例如:0xF3

    • 八进制

        八进制是以0开头,只包含0-7的字符串。

        例如:032

·         浮点数

        定义成含有小数点的数字。浮点数可以包含小数和指数部分。

        例如浮点数3.14可以表示成以下WMLScript 1.1编译器能够识别的几种形式:

    • 3.14
    • 3.14e0
    • 3.14E0
    • .314E1
    • 314e-2

        下面的形式都表示一个浮点数:

    • 十进制整数

例如:3

    • 十进制浮点数

例如:.14

    • 分数

例如:1/2

    • 指数

例如:e0

    一个浮点数必须至少有一个数,是十进制的小数点或者指数。
    指数是以eE开头,后面跟着一个整数。指数是以10为底的幂。例如:e010的零次幂,e-2等于0.01。指数可以带符号(+或者-,代表是正指数还是负指数)。
    一个超出定义范围内的浮点数将导致编译错误。一个下溢出将导致这个浮点数为0

o        字符串

    定义为在成对的双引号("")或者成对的单引号('')之间的内容。
    下面都是字符类型:

      • 'Goldwater Wins Nomination!'
      • "Tuesday, June 29, 1999"
      • "15% off retail"

    字符串是一个指向字符串所在位置的内存指针。在运行的时候可以修改字符串的值。WMLScript 1.1只允许成对的双引号或单引号。这意味着当使用一个单引号和一个双引号的时候将出现编译错误。
    有一些字符不能在字符串中直接体现出来。WMLScript 1.1支持特殊的转义来支持这些字符。全部的转义字符请见表3-9

3-9 转义字符

所代表的字符

符号

转义序列

单引号

` 

"' 

双引号

" 

"" 

反斜杠

" 

"" 

斜杠

/ 

"/ 

后退一格 

 

"b 

送纸 

 

"f 

换行

 

"n 

回车 

 

"r 

水平制表符 

 

"t 

使用十六进制引用字符(Latin-1 ISO8859-1

 

"xhh 

使用八进制引用字符(Latin-1 ISO8859-1

 

"ooo 

显示Unicode字符

 

"uhhhh 

o        布尔型

    定义为只有truefalse两个值的数。

o        无效(空)

    一个表示无效值的量(像C语言中的NULL)。


5. 保留字

    保留字在WMLScript 1.1中表示了特殊的意义,因此不能另外定义。在WMLScript 1.1中,保留字如下:

access

agent

http

if

break

continue

isvalid

meta

div

div=

name

path

domain

else

return

typeof

equiv

extern

url

use

For

function

user

var

header

while

 

 

    有一些保留字已经预先为将来的WMLScript版本保留:

case

finally

import

public

catch

private

switch

struct

class

sizeof

try

throw

const

super

do

export

debugger

default

enum

extends

    WMLScript没有使用的保留字:

delete

null

in

this

lib

void

new

With

 

变量与数据类型

本节介绍WMLScript 中的两个重要概念:变量和数据类型。

1. 变量

    变量是在脚本程序中具有值的符号名。使用变量来存储和改变程序的数据。

    注意:WMLScript 1.1仅仅支持函数内定义的变量或者是用来传送数值的参量。

    • 声明

    就是指定变量的名字。

    例如:
        var x;
        var x,y;
        var size=3;

    使用var关键字来定义一个变量。如果想在一条语句中声明多个变量,那么这些变量之间使用逗号“,”分开,定义使用分号“;”结束。
    WMLScript 1.1要求在使用变量之前定义变量。如果不是十分需要,没必要去初始化每一个声明的变量。如果不做初始化,它将自动初始化成为空字符串("")。

    • 作用域与生命期

    一个变量的作用域是指在程序中能够引用这个变量的一段代码。变量的生命期是指从变量声明开始到失效为止。生命期也被称为持久性。

    • 使用

    一个变量只能在其所定义的函数内使用。

例如:
    var myAge=25;
    var yourAge=25;
    var ourAge=myAge+yourAge;

    可以通过调用变量的名字来使用变量。在上面的例子中,变量ourAge对变量myAge和变量yourAge实行了求和的操作。


2. 数据类型

    数据类型是确定变量该是哪种类型的变量。

    例如:
    var flag=true;
    var number=12;
    var temperature=27.7;
    var number="XII";
    var except=invalid;

    WMLScript 1.1只支持内部定义的数据。没必要去指定变量的类型,变量在任何时候可以是以上五种数据类型中的一种。当需要同其他内部定义的数据相区别的时候,可以使用第五种数据类型。

    • 整数范围

    WMLScript 1.1所支持的整数范围。
    支持的范围是从-21474836482147483647。可以在运行期使用Lang库函数来取得这些值。
    Lang.maxInt()返回所能支持的最大整数值。
    Lang.minInt()返回所能支持的最小整数值。

    • 浮点数范围

    指以浮点数的精度所能表示的最小和最大数值。
    最大数值:3.40282347E+38
    最小的非零的数值(按照正常的精度):1.17549435E-38或更小。
    可以使用的Float库函数在运行期取得这些数值:
    Float.maxFloat()返回所能支持的最大浮点数值。
    Float.minFloat()返回所能支持的最小浮点数值。
    如果操作结果是一个不能被单精度浮点数所能表示的数值,那么结果将是invalid。如果操作结果发生下溢出,那么结果将是0.0。负零和正零是完全相等的。

    • 字符串

    由字母、数字或特殊字符组成。
    可以使用字符串来初始化字符串变量。可以使用WMLScript 1.1中定义的关于字符串的操作或String库中的函数来控制字符串。

    例如:
        var msg="Hello"
            var len=String.length(msg)
            var msg=msg+"World !"

    • 布尔型

    可以使用布尔类型去初始化或指定变量的数值。或者使用一个需要布尔值做为参数的语句。布尔值可以是数值或者是逻辑运算的结果。

    例如:
        var truth=true;
            var lie=!truth;

预编译头

预编译就是在编译阶段控制编译器的行为。预编译头一般在文件开头和函数声明之前指定。所有的预编译头都是以“use”加上指定的预编译属性。

1. 外部文件

    可以使用URLUniform Resource Locator)去调用一个WMLScript 1.1的文件。使用 use url”标签去调用一个在外部文件里的函数。
    例如:
        use url OtherScript "http://www.host.com/app/script";

    为了调用一个外部文件,必须按下面的方式指定:

    • WMLScript 1.1 资源所在的URLhttp://www.host.com/app/script
    • 资源的名字(OtherScript

    然后才可以在函数的声明内使用该资源。
    例如:

function test (par1, par2)
{
return OtherScript#check (par1-par2);
};

    调用的过程如下:

    • 找到WMLScript 1.1文件的URL
    • 函数从指定的URL位置装载文件。
    • 检测文件的内容,并执行check函数。

    use url”预编译头有自己局部命名空间。局部名字在整个文件中必须是唯一的。WMLScritp 1.1支持绝对URL和不带井号“#”和标识片段的相对URL。想了解更多的内容请查看http://info.internet.isi.edu/in-notes/rfc/files/rfc2396.txt
    对于相对URLURL的起始位置是当前文件所在的位置。
    被指定的URL中的内容要根据转义要求转义。在编译的时候编译器不会自动转义、检查URL的格式和校验其有效性。


2. 控制权限

    可以使用权限控制预编译头来保护文件的内容。必须在调用外部函数之前使用权限控制预编译头。当然多于一个以上的权限控制预编译头将导致编译错误。
    每当外部函数被调用的时候,编译器就会检查外部文件的控制权限,以决定调用者是否有该文件的使用权。权限控制预编译头通过指定domainpath属性来决定将要进行什么样的检查工作。如果文件有domain 或者path属性,那么文件所在的URL就必须和属性中的值一致。比较是按下面的步骤进行的:

    • 操作域与URL中的域后缀相匹配。
    • 操作路径和URL中的路径前缀相匹配。

    域和路径都依据URL大写规则。
    域后缀匹配是所有的子域从后向前都必须一致。
    例如:

        www.wapforum.orgwapforum.org相匹配,而不是forum.org

    路径前缀匹配指从前向后都必须一致。
    例如:
        /X/Y匹配/X,而不是/XZ

    默认的domain属性为当前的文件域,也就是“/”。
    为了使开发简单化,有时候不需要知道文件的绝对路径,而使用相对的URL。用户代理就将相对路径转换成为绝对路径,然后根据路径属性进行匹配。
    例如如果权限控制的属性为:

        use access domain "wapforum.org" path "/finance";

    可以使用以下的路径来调用指定文件中的外部函数:

        http://wapforum.org/finance/money.cgi

        https://www.wapforum.org/finance/markets.cgi

        http://www.wapforum.org/finance/demos/packages.cgi?x+123&y+456

    而以下的路径是被禁止的:

        http://www.test.net/finance

        http://www.wapforum.org/internal/foo.wml

    控制权限检查的默认值是不进行检查(disabled)。

    meta能够指定文件的属性名(property name)和属性值(content)。meta同样能指定文件的配置(scheme)。也许是一个表单或者是一个结构用来进行文件的内部解释。属性值都是字符串类型。
    meta从不定义任何属性值,也不知道用户如何解释meta。用户代理也不会理会meta中的内容。
    meta可以有以下属性:

    • name

        name指定供服务器使用的meta信息。
     例如:
                use meta name "Created" "18-June-1999";

     用户代理应当忽略这些属性。而服务器应该不能将这些信息透露给用户代理。

    • http equiv

       指定Meta信息应当被解释为HTTP的头。
        例如:
            use meta http equiv "Keywords" "Script, Language";

     按照这样命名的数据将按照无线对话层协议(Wireless Session Protocol)来解释或者将在达到用户代理之前进行解释。

    • user agent

        定义用户代理使用的数据。
        例如:
            use meta user agent "Type" "Test";

     这些数据必须立即发送给用户代理,并马上清除掉。

操作符与表达式

本节介绍WMLScript 支持的操作符,以及如何用这些操作符构造完整的表达式。

1. 赋值操作符

    指定一个变量的数值。
    例如:
        var a="abc";
            var b=a;
            var b="def"; //value of a is "abc"

    赋值运算符不需要指定使用对象,也不会改变赋值操作符右边变量的数值。最简单的赋值运算符就是等号“=”;其他赋值运算符见表3-10

3-10 赋值运算符

操作符

操作

= 

赋值

+= 

加上一个数或字符串,在赋值给右边

-= 

求差并赋值

*= 

求积并赋值

/= 

求商并赋值

Div= 

整除并赋值

%= 

求余数并赋值

<<= 

带符号左位移并赋值

>>= 

右位移并赋值

>>>= 

补零右位移并赋值

&= 

位与并赋值

^= 

位异或并赋值

|= 

位或并赋值


2. 数学运算符

    一些基础的数学运算符。
    例如:
        var y=1/3; //y=0.3333……
            var x=y*3+(++b); 

    WMLScript 1.1 以下所有的基础数学运算符如表3-11所示。

3-11 基础数学运算符

运算符

操作

+ 

数字相加,字符串相连

- 

相减

* 

相乘

/ 

相除

div 

整除

    WMLScript 1.1所能支持的复杂运算符如表3-12所示。

3-12 复杂数学运算符

运算符

操作

% 

求余数

<< 

按位左移

>> 

带符号右位移

>>> 

补零右位移

& 

位与运算

| 

位或运算

^ 

位异或运算

    WMLScript 1.1的基本一元运算符如表3-13所示。

3-13 一元运算符

运算符

操作

+ 

加 

- 

减 

-- 

前缀或后缀的自减

++ 

前缀或后缀的自加

~ 

按位求反

    运算过程当中,将按照表3-14进行以下隐含的转换。

3-14 转换规则

操作类型

转换规则

例子

布尔型

如果操作数是布尔型或者能够被转换为布尔型,那么将进行布尔运算并返回值

true && 3.4 => boolean
1 && 0 => boolean
"A" || "" => boolean
!42 => boolean 

返回invalid

!invalid => invalid
3 && invalid => invalid 

整数

如果操作数是整型或者能够被转换为整型,那么进行整数运算并返回整数值

"7" << 2 => integer
true << 2 => integer 

返回invalid

7.2 >> 3 => invalid
2.1 div 4 => invalid 

浮点数

如果操作数是浮点数或者能被转换为浮点数,那么将进行浮点运算并返回浮点值

返回invalid

字符串

如果操作数是字符串类型或者能够被转换为字符串类型,那么进行字符串运算并返回字符串

返回invalid

整数或浮点(一元)

如果操作数可以被转换成整数值,那么进行整数转换并返回整数值

+10 => integer
-"33" => integer
+true => integer 1
-false => integer 0 

如果操作数是浮点数或者能被转换为浮点数,那么将进行浮点运算并返回浮点值

-10.3 => float
+"47.3" => float 

返回invalid

-"ABC" => invalid
-"9e9999" => invalid 

整数或浮点

如果有一个操作数是浮点数,就将另外一个数转换为浮点数,进行浮点运算并返回浮点值

100/10.3 => float
3.4*"4.3" => float
"2.3"*"3" => float 

如果操作数是整数或者能够被转换为整数,那么进行整数运算并返回整数

33*44 => integer
"10"*3 => integer
"10"-"2" => integer 

如果操作数能被转换为浮点数,那么将进行浮点运算并返回浮点值

返回invalid

3.2*"A" => invalid
.9*"9e999" =>invalid
invalid*1 => invalid 

整数、浮点或字符串

如果操作数是整数或者能够被转换为整数,那么进行整数运算并返回整数

12+3 => integer
3<false => integer 

如果有一个操作数是浮点数,就将另外的操作数转换为浮点数,进行浮点运算并返回浮点值

32.4+65 => float
43.2<77 => float
9.9+true => float 

如果有一个操作数是字符串,就将另外的操作数转换为字符串,进行字符串运算并返回字符串

"12"+5.4 => string
"Hey"<56 => string
2.7+"4.2" => string 

返回Invalid

"A"+invalid => invalid 

任何类型 

任何类型都接受

a = 37.3 => float
b = typeof "s" => string


3. 逻辑运算符

    逻辑操作或和逻辑相关的运算。
    基础的逻辑运算如表3-15. 

3-15 比较操作符

操作符

操作

&&

逻辑与

||

逻辑或

!

逻辑反(一元)

    逻辑与只计算第一个操作数的值,结果为false或者invalid,那么整个结果就是false或者invalid。并且不计算第二个操作数的值。如果第一个操作数的值为true,那么整个结果就取决于第二个操作数的值。
    类似的,逻辑或也只计算第一个操作数的值,如果结果为true或者invalid,那么整个结果就是true或者invalid,并且不计算第二个操作数。如果第一个操作数为false,那么整个结果就取决于第二个操作数的值。
    例如:
        weAgree = (iAmRight && youAreRight) ||  (!iAmRight && !youAreRight);

    WMLScript 1.1只能使用布尔值来进行逻辑运算,因此就需要将其他类型自动转换为布尔型。
  
注意:如果与、或操作符的第一个操作数是invalid,那么将不计算第二个操作数的值。并且整个结果就是invalid
    例如:
        var a = (1/0)|| foo ();   // result: invalid, no call to foo ()
            var b = true || (1/0);      // true
            var c = false || (1/0);       // invalid


4. 字符串运算符

    和字符和字符串相关的运算。
    例如:
        var str = "Beginning" + "End";
            var chr = String.charAt (str,10)        // chr = "E" 

    +”和“+=”运算符用来连接字符串。其他有关字符串的操作全部在String库中。


5. 比较运算符

    比较两个变量的值,也常被称为关系运算符。
    例如:
        var res = (myAmount > yourAmount);
            var val = (( 1/0) == invalid);        // val = invalid 

    WMLScript 1.1支持表3-16中的比较操作符。

3-16 比较操作符

操作符

操作

小于

<=

不大于

==

相等

>=

不小于

大于

!=

不等于

    比较运算的规则如下:

    • Booleantruefalse大。
    • Integer:按照整数规则比较。
    • Floating-point:按浮点数规则比较。
    • String:按顺序比较字符串中的字符(字符的数值是在WMLScript 1.1中定义的)。
    • Invalid:如果只要有一个操作数是invalid,那么整个比较就是invalid

    在比较的过程中,将隐含地发生数据类型转换。请参见表3-14


6. 数组运算符

    String库内的函数将字符串看作为一个数组。并按照模仿数组的行为对其进行操作。
    例如:
function dummy()
{
  var str = "Mary had a little lamb";
  var word = String.elementAt (str,4,"");
};

    WMLScript 1.1不支持普通的数组。但是String库支持对字符串的类数组操作。
    一个字符串可以包含程序员所指定的多个分隔符。String库中有创建和管理字符和字符串的函数。


7. 逗号运算符

    将多个表达式连接在一起。
    例如:
for (a=1, b=100; a < 10; a++,b++)
{
  //... do something ...
};

    逗号运算符的结果是第二个操作数的结果。
    在为声明的变量赋值的逗号,不是逗号运算符。一般来说逗号运算符都要使用括号保护起来。
    例如:
var a = 2;
var b = 3, c = 3;
myFunction("Name", 3*(b* a, c)); // Two parameters: "Name", 9


8. 条件运算符

    根据布尔运算的结果给一个变量赋值。
    例如:
        myResult = flag ? "Off" : "On (value=" + level + ")"; 

    条件运算符其实是个if-then语句,它们的组织方式如下:
        d = operand1 ? operand2 : operand3
        operand1 是计算出的条件。如果条件是true,表达式的值就是operand2。如果条件是false或者invalid,那么结果就是operand3


9. typeof运算符

    通过返回整数来表示给定的表达式的类型。
    例如:
        var str = "123";
            var mytype = typeof str;        // myType = 2 

        WMLScript 1.1内部所支持的基本数据类型如表3-17

3-17 typeof返回值

类型

返回值

整数

0

浮点数

1

字符串

2

布尔型

3

无效

4

    typeof操作符不会自动将结果转换为其他的类别。


10. isvalid运算符

    检测给定表达式的有效性。
    例如:
        var str = "123";
            var ok = isvalid str;        // true
            var tst = isvalid (1/0);     // false 

    如果表达式是有效的,那么返回值就是true,否则就是falseisvalid操作符不会将返回结果自动转换为其他类型。


11. 表达式

    由操作符、常量、数值函数或变量组成。
    以下的例子是一个常量或者是变量:

    • 567
    • 66.77
    • "This is too simple"
    • 'This works too'
    • true
    • myAccount

    复杂的表达式可以使用简单的表达式、操作符和函数调用组成。

    • myAccount + 3
    • (a + b) / 3
    • initialValue + nextValue(myValues);

    WMLScript 1.1支持大多数其他编程语言都支持的表达式。

函数

一个WMLScript 函数作为一个WMLScript 编译单元(编译单元通常是一个WMLScript文件)的一部分,通过名字来标识,可以被其他函数调用而进行一系列的操作,并返回一个值。下面如何声明并调用函数。

1. 函数声明

WMLScript 1.1中函数声明是指声明函数的调用参数和函数体。所有的函数都有以下特点:

    • 函数声明不能嵌套。
    • 函数名字在同一个文件里必须唯一。
    • 函数的调用都是通过传参数值来实现。
    • 调用函数的时候,参数个数和类型必须和函数声明保持一致。
    • 函数的参数就好像是函数体内的局部变量,在函数调用的时候被初始化。
    • 函数始终有返回值,默认是空字符串("")。return语句可以来指定函数的返回值。
    • 可以使用extern关键字来声明一个外部函数。

function currencyConverter(currency, exchangeRate)
{
  return currency*exchangeRate;
};

extern function testIt()
{
  var USD = 10;
  var FIM = currencyConverter (USD, 5.3);
};


2. 函数调用

        函数调用将返回一个值,例如一个计算的结果。函数如何调用决定于函数是在哪儿声明的。

    • 内部函数

    声明函数和调用函数在同一个文件中,就称为内部调用。
    例如:

function test2 (param)
{
  return test1 (param+1);
};

function test1 (val)
{
  return val*val;
};

    内部调用是很简单的。只要使用函数名,给出参数使用分号结尾就可以啦!当然,参数的数目和类型必须和函数的声明相符合。
    一个本地函数可以在其声明之前被调用。

    • 外部函数

    一个在外部文件声明的函数的调用。
    例如:

use url OtherScript "http://www.host.com/script";

function test3(param)
{
  return OtherScript#test2(param+1);
};

    调用外部函数必须在前面加上外部文件的名字。
    必须使用“use url”来指定外部文件。预编译头将外部文件映射为一个可以在内部使用的标识。然后使用这个标识加上井号“#”和标准的函数调用来实现外部调用。

    • 库函数

    指的是WMLScript 1.1标准的库函数调用。

    例如:

function test4(param)
{
   return Float.sqrt(Lang.abs(param)+1);
};

    调用标准函数可以通过函数库的名字加上点号“.”和库函数的标准调用来实现。

语句

WMLScript 语句是由关键字和表达式按照一定的语法格式构成的。在书写程序时,一条语句可以占用多行,一行中也可以包含多个语句。

 

1. 空语句

    空语句只包含一个分号,例如:

    //This is a empty statement

    空语句常用于程序中某处语法上需要一条语句,但实际上又没有操作可执行的情况下。
    例如:

while (!poll(device));      // Wait until poll() is true


2. 表达式语句

    表达式语句用于指定参数的值,计算数学表达式,调用函数等等。即在一个表达式后面加上“;”号就形成一个表达式语句。
    例如:

str = "Hey" + yourName;
val3 = prevVal + 4;
counter++;
myValue1 = counter, myValue 2 = val13;
alert("Watch out!");
retVal = 16*Lang.max(val3, counter);


3. 块语句

    块语句以“{”开始,并以“}”结束,其间封装一个语句序列,或者被称为复合语句。
    例如:

{
  var i = 0;
  var x = Lang.abs(b);
  popUp("Remember!");
}

    块定义可以在任何只需要一条语句的地方使用。


4. 变量语句

    变量语句用来声明一个变量并对变量进行初始化(若没有初始化,变量值缺省为空字符串)。变量语句的一般格式为:

        var 变量名[=初始值][,变量名[]];

    例如:

function count(str)
{
    var result = 0;        // Initialized once
    while(str != "")
  {
        var ind = 0;       // Initialized every time
         // modify string
     };
  return result
};

 

function example(param)
{
    var a = 0;
    if (param > a)
  {
        var b = a+1;  // Variables a and b can be used
    }
  else
  {
        var c = a+2;  // Variables a, b, and c can be used
    };
    return a:         // Variables a, b, and c are accessible
};

    合法的变量名必须是唯一的。它的作用域是当前的文件,表达式在每次调用的时候都重新计算。


5. if语句

    一条或者两条根据条件的布尔值来判断其是否执行的语句。
    if语句通常包括一个条件表达式,还要有一个或两个语句。If语句有两种形式,一种形式为:

            if(表达式) 语句

    表达式的值是布尔值或invalid值。

    另外一种形式为:

      if(表达式)
        语句
        else
            语句

    if语句中,如果第一个条件为true将执行第一条语句。如果为false或者invalid,那么就执行第二条语句。所执行的语句可以是WMLScript 1.1所规定的任何语句,包括其他嵌套的if语句。
    例如:

if (sunShines)
{
    myDay = "Good"
    goodDays++;
} else
myDay = "Oh well...";


6. while语句

    通过while语句,可以在给定条件成立的情况下,重复执行某个语句(可以是块语句)。
    while语句的格式为:

        while(表达式)语句

    表达式的值是布尔值或invalid值,如果是其他类型,可以通过类型转换为布尔型。执行时先计算表达式的值,如果值为true,则重复执行语句;表达式的值为falseinvalid,则不执行语句,跳出循环,执行while语句后面的语句。每一次重复,都要重新计算表达式的值,当循环条件为真的时候将反复地计算表达式的值。
    例如:

var counter = 0;
var sum = 0;
while (counter < 5)
{
    counter++;
    sum += c;
};

    只要循环条件为真,循环将一直执行下去。


7. for语句

    for也是一种循环语句。它的一般形式为:

        for(表达式1;表达式2;表达式3
        语句

    或者是另外一种形式:

        forvar变量声明列表;表达式2;表达式3
        语句

    for语句有三个可选的部分组成。每个部分使用分号分开,并且都包含在一个括号中,后面紧接所需要执行的循环语句。
    典型的,第一个表达式(var index = 0 如下例)是用来初始化变量的数值。在表达式中可以使用关键字var来声明和初始化一个变量。变量的作用域将从声明的地方开始直到函数结束。
    第二个表达式可以是任何的WMLScript 1.1布尔表达式。每次开始循环之前都会计算表达式的值。如果结果为true,那么就执行循环。这个表达式是可选的。如果被省略,那么条件值永远是true
    第三个表达式是用来更新或者增加记数器变量的。只要循环条件为真,这条语句就被执行。
    例如:

for (var index = 0; index < 100; index++)
{
    count += index;
    myFunc(count);
}; 


8. break语句

    中断当前的循环,程序将从中断的地方开始继续执行。break语句只能用在whilefor语句中,即用在它们的循环体中。当循环体中遇到break语句时,循环立即终止,程序跳过break语句后的其余语句,从循环语句后的第一条语句继续执行。
    例如:

function testBreak(x)
{
    var index = 0;
    while (index < 6)
  {
        if (index == 3) break;
        index ++
    };
    return index*x;
};

    while或者for语句外使用break语句将导致编译错误。


9. continue语句

    中断执行在循环内的语句,直接执行下一个循环。Continue语句只能用在whilefor语句的循环体中,用来终止当前的一次循环。当循环体中遇到continue语句时,程序跳过continue语句后的其余语句,开始下一次循环。
    例如:

var index = 0
var count = 0
while (index < 5)
{
    index++;
    if (index == 3)
        continue;
    count += index;
};

    continue不会中断循环的执行:

    • while循环中,将返回到条件判断的语句。
    • for循环中,将返回到更新的语句。

注意:在for或者while语句外使用continue将导致编译错误。


10. return语句

    在函数体内使用,用来指定函数的返回值。return语句用在一个函数的函数体里,为函数返回一个值。如果一个函数没有return语句,或者虽然有,但是没有执行到return语句,则函数返回一个空字符串。
    return语句的形式为:

        return [表达式];

 例如:

function square (x)
{
    if (!(Lang.isFloat(x))) return invalid;
    return x * x;
}

九、WMLScript函数库

WMLScript 支持几个标准的函数库:LangFloatStringURLWMLBrowserDialogsConsole 。每个库中分别包含一组函数,可以用“库名.函数名”的形式来调用库函数。

十、WAP辅助工具

下面介绍的是在网络上可以找到的有关WAP开发的辅助工具。

1. WAPtelnet

    URLhttp://www.webdynamite.com
    适用于Win95/98/NT/2000SolarisHP-UXAIXLinuxMacOS操作系统。
    WAPtelnet是一个telnet客户端。通过它可以连接到UNIX,路由器和其他支持telnet服务的机器上。WAPtelnet使得使用WAP进行远程管理成为可能。

2. PolarWAP Static Compiler 1.2

    URLhttp://www.polarwap.com/downloads/index.htm
    适用于Windows 95/98/NT/2000操作系统。
    使用PolarWAP Static Compiler来提高应用程序的性能。当WAP网关处理WML内容的时候,它们首先需要将内容翻译成二进制再提供给移动设备。这是一个缓慢而且容易出错的阶段。当处理编译后的WML页面,相反就快多了。

3. Enhydra

    URLhttp://www.enhydra.org/software/downloads/index.html

  • 包括数据组件设计室(Data Object Design StudioDODS)和XML编译器(XML ComplierXMLC)。含源程序。
  • 下载Enhydra企业版,包括EJBCORBA技术。
  • 下载新的IDE add-in wizards
  • 下载新的Enhydra Servlet Debugger
  • 下载新的演示、应用、工具、补丁等等。

4. WAP2PDF

    URLhttp://www.sanface.com/
    WEB或者WAP上创建PDF文件。

5. WAP email form 1.0

    URLhttp://www.jumbuck.com/downloads/emailform_1_0.zip
    将这个使用Perl编写的代码加入到站点里面。就可以收发E-Mail了。有一个简单的readme文件来解释如何建立CGI并测试。

6. HAWHAW

    URLhttp://www.hawhaw.de/
    提供的适用于PHPWAP工具包,将会使WAP开发更加简单。

7. Zygo Communications

    URLhttp://www.z-y-g-o.com/
    这些工具都是Zygo自己内部使用的工具,也许对其他的WAP开发人员有用。免费的,也没有任何保证。如果崩溃了,读者必须自己承担责任。

  • CGI::WML

        一个LDS的子类CGI.pm Perl模块。用来生成WML输出名字转换。CGI::WAPCPANhttp://www.perl.com/CPAN)作为CGI::WML-0.04
        这个版本只适合于CGI.pm 2.67。需要使用最新的版本来升级。

  • WMLWMLC
  • wml_to_wmlc.pl

        一个用Perl语言编写WMLWMLC转换器。基于XML::Parser。不但能转换,而且做一定的优化工作。

  • wmlc-0.001.tar.gz

        一个用C语言编写的WMLWMLC转换器。基于Thomas Neilwml_tools工具包。同样也有Perl界面,但是还没有完成。

  • HTMLWML
  • html_to_wml.pl

        一个使用Perl编写的工具。可以将HTML页面转换成WML页面。CGI::WML以上包括了HTMLWML的转换

  • WML URL效验
  • waptest.pl

        一个使用Perl编写的,基于URL语法编写的WML URL合法检测程序。

  • Header dump
  • hd.pl

        查看WML或者HTML浏览器的请求头数据。HTML或者WML输出,依据发送请求的浏览器。

 

posted on 2007-09-24 15:41  exce4  阅读(774)  评论(0编辑  收藏  举报

导航