WML 语法
<jsp高级编程238>
下来将详细地讲述WML 文档的各个方面使读者掌握WML 文档的用法
由于前面的WAP 我们已经介绍过了相信读者应当能够理解因此这里直接叙述
WML 语言WML 语法主要有如下几部分
基本规则
<1>WML 使用XML 文档字符集目前支持Unicode 2.0 WML 的所有标签属性和
规定的可接收值必须小写CARD 的名字和变量也是区分大小写的对于连续的空字符
只显示一个空格
<2>标签内属性的值必须用符号或括起来属性名和值之间不能有空格
对于不成对出现的标签必须在> 前加/ 比如<br/>
<3>对保留字符的处理对应的取代字符见表5.3
表5.3 保留字符
保留字符 对应的取代字符
< <
> >
? &apos
" "
& &
$ $$
空格  
- ­
基本格式和文件头
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
千万注意字母的大小写对于一个DECK 其文件大小最好不要超过1.2K
<2><wml>标签和HTML 中的<html>标签一样用来表明这是一个WML 的DECK
它有一个可选的xml:lang 属性来制定文档的语言比如<wml xml:lang="zh">表示文档语言
为中文
<3><head>标签包含了该DECK 的相关信息<head>标签之间可以包含一个<access>
标签和多个<meta>标签<access domain="域" path="/路径" />相当于HTML 中的<BASE>
标签指定该DECK 的访问控制信息它用两个可选的属性domain 用来指定域默认值
为当前域path 用来指定路径默认值为/ 即根目录由于<access>单独使用所以要
用/ 结尾以后对于类似的情况不再赘述
<meta 属性 content="值" scheme="格式" forua="true|false"/>和HTML 中的类似提供
了该DECK 的meta 信息属性是必选的包括一下三种情况:
name="name": UP.Link Server 忽略meta 数据
http-equiv="name": UP.Link Server 将meta 数据转为HTTP 响应头(同HTML)
user-agent="agent":UP.Link Server 直接将meta 数据传给手机设备
content 属性也是必选的其内容根据属性而定scheme 属性目前尚不支持forua 为
可选属性
目前支持的meta 属性如下所示:
<meta http-equiv="Cache-Control" content="max-age=3600"/>
指定DECK 在手机内存缓存中的存储时间段默认的为30 天(除非内存耗尽) 在该期
间手机对于访问过的DECK直接从缓存里调用如果信息是对时间敏感的可以用max-age
指定DECK 在缓存里的生存期最小单位是秒如果指定为0 则每次都需通过连接服务
器来调用该DECK
<meta user-agent="vnd.up.markable" content="false"/>
和
<meta user-agent="vnd.up.bookmark" content="指定的URL"/>
类似于普通浏览器的书签功能当用户将一个CARD 做了书签后手机浏览器首先用
一个标记记录该CARD 这个标记默认的是<card>标签中的title 属性(以后会讲到) 然后当
用户选择了该书签以后浏览器就会打开被记录的URL 但是因为在默认的情况下手机
会记录所有的DECK 所以一般<meta>被用来使手机不要记录当前的URL 即<meta
user-agent="vnd.up.markable" content="false"/> 此外如果要为书签指定不同于当前DRECk
的URL 用<meta user-agent="vnd.up.bookmark" content="指定的URL"/>
<4>一个DECK 可以包含多个CARD 每个CARD 的内容可能不止一屏显示注意
第二部分 JSP 技术和XML 技术
DECK CARD 和屏幕显示范围的关系一个CARD 用<card>和</card>包含<card>可以
包含以下可选的属性
<card id="name" title="label" newcontext="false" ordered="true" onenterforward="url"
onenterbackward="url" ontimer="url">
id 属性用来指定CARD 的名字可用来在CARD 间跳转相当于在HTML 中在页内
跳转时用<A NAME="jumpHere">
title 属性用来作为书签的标记该属性一般不会显示在屏幕上
newcontext 属性默认值为false 用来指示当跳转到本CARD 时手机是不是要清除
以前保留的信息包括变量堆栈里的历史记录重新设置手机状态等
ordered 属性默认值是true 表明该CARD 里的内容是按固定的顺序显示还是按用
户的选择来显示这样做是为了方便填表单当ordered 设置为true 时如果一个表单的内
容不能在一屏里显示完就分成多屏显示当ordered 设置为false 时手机可以显示一个
概要CARD 来总结有效的选项用户可以从中选取表单选项来填写
onXXX 属性类似于HTML 标签中的onXXX 属性用来捕捉事件当事件被触发时
执行指定的操作(任务) 在这里是转向某个URL
显示文本
在文本的显示上WML 基本和HTML 相同文字段落包含在<p align= "alignment"
mode=" rapmode">和</p>之间align 属性指定该段文字的对齐方式默认的是left 其他
可选择right 和center mode 属性指定当一行显示不下所有的文字时是否自动换行默认的
是自动换行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 属性和前面提到的一样是对齐方式表格中可
以包含文字和图片
程序清单5.32(example3.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>
<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 键的标记显示在屏幕的软
第二部分 JSP 技术和XML 技术
按钮区所以通常可以将属性作为提示文字使用
然而以上的连接在WML 里只是任务的一种情况为了能够使用其它任务所以引
进了新的标签<anchor title="label">任务标签 文本</anchor> <a>其实是当任务标签为<go/>
时的简单表示方式
程序清单5.33(example5.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>
<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 包括DECK 的第一个CARD 或者指定的
CARD 语法如下:
<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
Method 属性和HTML 中的表单FORM 的method 属性一样指定表单是以get 的方式
还是post 的方式递交以便cgi 处理默认的值为get 但如果未指定method 而<go></go>
间存在<postfield> 手机自动以post 方式传递
accept-charset 属性可覆盖在HTTP 头里指定的字符集可以写多个字符集如
accept-charset="US-ASCII ISO-8859-1"
<postfield name="name" value="value"/>类似于HTML 表单FORM 中的<INPUT
TYPE="HIDDEN" NAME="变量名" VALUE="值"> 通过它可以向指定的URL 传递以“变
量名/值”形式的数据name 和value 属性都是必选的注意只有这里的变量是用来递交给
CGI 程序的
除了<postfield> 还可以在<go>和</go>间加入一句或者多句<setvar name="name"
value="value"/> 该语句的意思是当触发某一事件时给变量赋值
要注意的是当<go>和</go>之间没有任何语句时要用<go/>的形式 这点比较特别
例:
<anchor title="Link1"><go href="test.wml"/>News</anchor>
第5 章 XML 简介
<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>中一般用在覆盖DECK 级的
<do>
WML 中的控件
对程序设计有所涉及的读者应该很清楚一般来说表单是应用程序的图形用户界面
在WML 中表单提供了用户与网页的交互功能对表单的控制能力可以证明一个HTML
设计者是否够专业而且很多交互功能也必须依赖表单
WML 没有表单属性但是WML 可以直接使用控件同样可以达到使用表单的效果
因此使用控件的水平可以体现一个WML 设计者的制作水平因此下面我们介绍的重点
是WML 支持的各种类型的控件
WML 控件有Select List 和Input Box 两个系列每个系列另外包含几个子系列基本
可以满足表单设计的需求
1 选择列表控件Select List
Select 有两对很重要也很容易混淆的属性name value iname ivalue 这4 个属性
的区别和用途不太容易描述清除看了后面的例子会很容易理解
每个Select 是一个或多个Option 的集合Option 地结果返回给Select 元素的name 和
iname 例如下面的代码
例:
<select name="name" iname="iname" value="value" ivalue="ivalue">
<option value="S">sina</option>
<option value="Y">yahoo</option>
</select>
相关属性:
multiple 这个布尔变量的值决定是否允许多重选择值为True 时Select 控件允许复选
否则相反
name 和 Value: 这一组变量的主要作用是获取于该option 的返回值value 提供name
的缺省值
iname 和 ivalue: 与上一组参数功能相似不同的是ivalue 返回有效Option 的序列号
被选中的控件用它的序号表示0 代表没有option 被选中假如第二个和第三个同时被选
中就表示为 2;3
title 作为标题参数提供给浏览器但是不同的浏览器处理方式有所不同有些浏览器
直接显示选项内容不显示标题有的浏览器显示标题按选择键进入选择界面
第二部分 JSP 技术和XML 技术
tabindex 提供给浏览器的控件序号参数
2 选项控件Option
Option 只有包含在Select 内才有意义无法单独使用
相关属性:
value: Option 的返回值假如当前Option 被选择这个Value 的值会被传送到Select
元素的Name 变量
title :供浏览器显示的选项标题
onpick:如果当前Option 被点选浏览器跳转到指定的URL 如下例所示
例:
<card>
<p>Please choice your favourite Web.<br/>
<select name="X">
<option value="S">sina</option>
<option value="Y">yahoo</option>
</select>
<p>
</card>
上例是一个基本的单选列表选择的结果被赋值给X 下面我们来学习前面所说的两
组属性的用法
例:
<card>
<p>Please choice all your favourite Web.<br/>
<select name="X" iname="I" ivalue="1;3" multiple="true">
<option value="S">sina</option>
<option value="Y">yahoo</option>
<option value="N">netease</option>
</select>
<p>
</card>
这里是一个使用了iname 和ivalue 的多选列表I 被预置为 1;3 假如用户选择了sina
和yahoo X 被赋值为 S;Y I 被赋值为 1;2 假如用户不做任何选择I 等于1;3 X 内容
为空下面我们将学习onpick 属性的功能如下
例:
<p>Jump to your favourite Web.<br/>
<select>
<option onpick="http://wap.sina.com.cn">sina</option>
<option onpick="http://wap.chnmobile.net">china mobile</option>
</select>
<p>
</card>
这里演示了Option 的onpick 功能不管Option 的状态如何只要它被点选浏览器
第5 章 XML 简介
就会跳转到指定的URL
3 文本框控件Input
文本框控件Input 用来输入文本控件的使用格式如下
<input name="variable" title="label" type="type" value="value" default="default"
format="specifier" emptyok="false|true" size="n" maxlength="n" tabindex="n"/>
相关属性:
title 该输入框的标题
type 默认值为text 如选择password 则输入的数据显示为*
name 指定了用来存储该输入文本的变量名字
value 与select 的相同属性很相似name 用于存储变量数据value 用于提供缺省值
format 用来格式化输入的数据可用的标记如下使用时可用“一位数字标记”和“*
标记”的形式前者代表N 个标记型字符如3X 后者代表任意个(小于maxlength 属性的
值)标记型字符format 属性所用到的标记性字符如表5.5
表5.5 format 属性所用到的标记
标记 描述
A 任何符号或者大写字母(不包括数字)
A 任何符号或者小写字母(不包括数字)
X 任何符号数字或者大写字母(不可改变为小写字母)
X 任何符号数字或者小写字母(不可改变为大写字母)
N 任何数字(不包括符号或者字母)
M 任何符号数字或者大写字母(可改变为小写字母)或者多个字符默认为
首字大写
M 任何符号数字或者小写字母(可改变为大写字母)或者多个字符默认为
首字小写
maxlength 属性指定了用户可输入的最大字符长度最大限制为256 个字符
emptyok 属性表示用户可否不填输入框默认为false 即要填
size 属性输入框显示长度目前未被支持
tabindex 属性类似于在HTML 表单中按Tab 键后焦点落在哪个选项上该值决定
了这个选择顺序数字大的排在后面目前未被支持读者可以看下面一个简单的代码片
断考虑一下它的含义
例:
<card>
<p>First name:
<input type="text" name="first"/><br/>
Last name:
<input type="text" name="last"/><br/>
Age:
<Input type="text" name="age" format="3N"/>
</p>
第二部分 JSP 技术和XML 技术
</card>
4 计时器控件Timer
计时器控件timer 可以用来在用户不进行任何操作的一段时间后自动执行一个任务
任何激活CARD 页面的任务和用户操作都会启动timer 而任务进行时timer 就停止每
个CARD 只能有一个timer 一个timer 只能触发一个任务语法如下
<timer value="value"/>
其中value 为必选属性用来设置定时器的定时值最小单位为0.1 秒
相关属性:
value: 倒计时的点数每一单位等于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>
<card id="first" ontimer="#next">
<timer value="100"/>
<p>Wait ten seconds</p>
</card>
<card id="next">
<onevent type="timer">
<go href="#first"/>
</onevent>
<timer value="10"/>
<p>Wait one second</p>
</card>
</wml>
事件
WML 的事件基本上分为两大类一类是键盘(包括软硬按钮)输入事件用<do>标签
来处理另一类是相关页面内部的事件用<onevent>标签来处理
1 外部事件
<do>标签的语法如下
<do type="type" label="label" name="name" optional="false|true">任务</do>
任务就是以前提到的4 种任务<do>的属性中type 是必选的其他为可选相关的
属性说明如下
label 属性指定了软按钮在屏幕上的显示文本目前type 属性为delete help prev
时该属性无效
name 属性为<do>取个名字同一的CARD 里的<do>不能重名如果CARD 级的<do>
和DECK 级的<do>同名则覆盖DECK 级的<do>
optional 属性指定手机是不是可以忽略这个事件默认值是false
type 属性指定触发的事件常见的事件类型如表5.6 所示
第5 章 XML 简介
表5.6 事件类型
type 值 触发原因
accept 调用ACCEPT 按钮机制
delete 调用DELETE 按钮机制
help 调用HELP 按钮机制
options 调用选择按钮机制
prev 调用PREV 按钮机制
reset 调用清除和重新设定手机状态时的RESET 机制(目前不支持)
通过分析下面的例子相信读者会对这些有所了解
程序清单5.34(example11.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>
<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>
2 内部事件
内部事件主要有<onevent>与<timer>两种现在分别介绍如下
1 <onevent>的语法如下
<onevent type="type">任务</onevent>
必选属性type 的取值如表5.7 所示
第二部分 JSP 技术和XML 技术
表5.7 <onevent>标签type 属性的取值
type 值 如果用户执行了以下操作就执行任务
onpick 用户选择或不选一个<option>项时
Onenterforward 用户使用<go>任务到达一个CARD 时
onenterbackward 用户使用<prev>任务返回到前面的ARD 时或者按BACK 按钮时
ontimer 当<timer>过期时
具体的用法如程序清单5.35 所示
程序清单5.35(example12.wml)
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.com/DTD/wml_1.1.xml">
<wml>
<!-- this deck can't use in Ericsson r320sc because r320sc haven't accept button-->
<card id="start">
<do type="accept" label="next">
<go href="#two"/>
</do>
<p>This is the first card.</p>
</card>
<card id="two">
<do type="accept" label="next">
<go href="#three"/>
</do>
<onevent type="onenterbackward">
<go href="#temp"/>
</onevent>
<p>This is the second card.</p>
</card>
<card id="three">
<do type="accept" label="back">
<prev/>
</do>
<p>This is the thired card.</p>
</card>
<card id="temp">
<do type="accept" label="start">
<go href="#first"/>
</do>
<p>haha you are lost!</p>
</wml>
2 <timer/>事件<timer>事件可以用来在用户不进行任何操作的一段时间后自动
第5 章 XML 简介
执行一个任务任何激活CARD 页面的任务和用户操作都会启动<timer/> 而任务进行时
<timer/>就停止每个CARD 只能有一个<timer/> 一个<timer/>只能触发一个任务语法
如下
<timer name="variable" value="value"/>
其中name 为可选属性指定为一个变量名当退出该CARD 时该变量存储此时定
时器的值当定时器超时时手机将该变量设为0 value 为必选属性用来设置定时器的
定时值最小单位为0.1 秒
程序清单5.36(example13.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>
<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>三者必须严格按以上顺序写否则将会出
错因为和XML 一样WML 的格式要求也是相当严格的
5.5.4 用JSP 创建WAP 应用
使用ASP 或者JSP 来创建动态WML 内容是非常容易的唯一要注意的就是配置服
务器使它的脚本输出类型为"text/vnd.wap.wml" 或者在JSP 脚本中直接设置输出类型
程序清单5.37 是一个用JSP 输出动态WML 内容的例子
程序清单5.37(wap.jsp)
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
第二部分 JSP 技术和XML 技术
"http://www.wapforum.org/DTD/wml_1.1.xml">
<% response.setContentType("text/vnd.wap.wml"); %>
<wml>
<card id="start">
<do type="accept">
<go href="index.jsp#test"/>
</do>
<p>用JSP输出动态WML:<br/>
选择Accept继续!<br/>
</p>
</card>
<card id="test">
<do type="prev">
<prev/>
</do>
<%
out.println("<p>");
out.println("你好测试成功!这是使用JSP程序产生的输出<br/>");
out.println("</p>");
%>
</card>
</wml>
在上面的程序中关键之处在于使用了JSP Response 对象的setContentType()方法设定
输出文件类型为text/vnd.wap.wml 这样尽管在服务端运行的是JSP 程序但是传送到无线
上网设备中的确是标准的WML 文件自然可以被上网设备的浏览装置浏览
5.6 本 章 小 结
这一章中我们主要对XML 技术做了初步的了解还简要地介绍了XHTML 的概况
WML 的语法知识其中后面两部分的内容不是十分重要读者不需要花太多的时间去
学习它们至于JSP 技术如何与XHTML WML 等技术结合起来相信很多读者都十分关
心这个问题我们认为只要掌握了XML 技术与JSP 技术是如何结合起来的那么其他
的问题就可以触类旁通迎刃而解了毕竟XHTML WML 都是XML 的子集在本质上
与XML 没有太大的区别学完本章后如果读者可以读懂XML 文件并且可以自己编写
一些简单的XML 文件那么我们的目标就已经达到了