程序举例 假设我们需要开发一个WML应用,WAP用户可以通过职员及其电话号码列表来查询职员信息。现在我们暂时有两个职员的数据,但将来还需要增加职员数量。因此,我们需要将职员数据保存在一个文本文件中,以便将来增加数据。该文本文件中的数据可通过随后编写的动态WML页面来显示。
首先,我们建立一个名为“people_data.txt”的文本文件,来存放职员信息,内容如下:
# Name|phone num|fax num|Title
Cao Jian|123-4567|098-7654|Director of OS Development
Zhang San|123-4568|098-7655|Senior VP of OS Research
其中,“|”符号是用来区别字段的,“#”是用来注释数据结构的。
为了说明使用Perl来编写的必要性,我们先给出使用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 title="Telephone Book" id="index">
<p>
Welcome to NEW Inc. Telephone Book
<a href=> </p>
</card>
<card title="List of Names" id="view">
<p>
<a href=> <a href=> </p>
</card>
<card title="Info for Cao Jian" id="cao_info">
<p>
Director of OS development
Phone number: 123-4567
Fax number: 098-7654
</p>
</card>
<card title="Info for Zhang San" id="zhang_info">
<p>
Senior VP of OS research
Phone number: 123-4568
Fax number: 098-7655
</p>
</card> </wml>
通过这个程序我们可以看到,如果增加新的职员,那么我们就不得不重新修改程序文件。这显然不是一个好办法。因此,我们设计了people_data.txt文本文件,可以随时增加职员数据,然后使用Perl实现上述WML页面的任务。我们的目标是,程序设计好后无需改动,只需通过给文本文件添加职员数据,就可以通过Perl编写的WML页面实现对增添职员后数据的浏览。
使用Perl编程时,最先需要完成的是设置我们的Perl环境。我们可以使用CGI模块来进行HTTP数据显示和处理,代码如下:
#!/usr/bin/perl -w
use strict;
use CGI qw/:standard/;
# Our CGI object
my $q = new CGI;
接下来,我们使用Perl语言编写上述WML页面的主体部分,同时建立标量变量,来保存文本文件名,以备后面从中读取数据。另外创建动态ID,这里用"a"表示,用于标识每一条职员数据,即一条记录。我们的目的是一次性地将所有的职员数据都生成卡片,然后使用一个初始化的缓冲区来显示职员的数据内容。这段代码如下:
# 定义获取职员信息的数据文件
my $data = "people_data.txt";
# 显示标题的卡片
my $title_card = qq (
<card title="Telephone Book" id="index">
<p>
Welcome to NEW Inc. Telephone Book<br/>
<a href=> </p>
</card>
);
# 初始化第一条记录的ID
my $id = "a";
# 开始创建浏览卡片
my $view_card = '<card title="All names in directory" id="view">
<p>
Click on a name for more info<br/>';
# 用于临时存放卡片信息的变量(相当于缓冲区)
my $all_info_card;
下面,我们要打开数据文件,当然打开前要检查权限,以保证我们真的能够打开,然后进行数据的读取。读取时,指定文本文件中以“#”开头的行仅作注释之用,不属于被读的内容。在读取数据的过程当中,我们需要做一定的检查,以保证每个部分的确有数据。在这里,我们把从文件中提取的数据传给两个子过程,它们将返回由这些参数数据所确定的卡片。注意我们使用了Perl的“ .= operator”运算符,它使得子过程返回的字符串将不断地扩充。实现这段任务的代码如下:
# 读取指定文件中的数据
open(FILE,"$data") || die "Can't open $data: $!\n";
while (<FILE>) {
chomp;
next if (/^\#/);
my ($name, $phone, $fax, $position) = split(/\|/);
# 调用子过程,创建浏览卡片
$view_card .= build_view_card($name, $phone, $fax, $position);
# 调用子过程,创建职员信息卡片
$all_info_card .= build_info_card($name, $phone, $fax, $position);
}
其中调用的子过程build_view_card的代码如下:
sub build_view_card {
$id++;
my ($name, $phone, $fax, $position) = @_;
my $info_item = qq (
<a href=> );
return $info_item;
}
它的功能是接收参数数据,并把这些数据插入到一个简单的模板里面。由于我们每次都在增加$id变量的数值,从而保证每个记录都有唯一的id号。这是因为Perl允许我们直接使用 ++ 操作符,使得$id变量的值从'a'增加到'b'、'c'等进行递增。
另一子过程build_info_card的代码如下:
sub build_info_card {
# 定义用于显示单个职员信息的卡片
my ($name, $phone, $fax, $position) = @_;
my $info_card = qq (
<card title="Info for $name" id="$id">
<p>
$position<br/>
Phone number: $phone <br/>
Fax number: $fax <br/>
<do type="prev"><prev/></do>
</p>
</card>
);
return $info_card;
}
它的功能是定义另一卡片,以显示每个职员的信息。由于我们已经在前面的子过程中增加了$id的数值,所以我们在这个子过程中所需做的只是返回一个新的卡片。
以上的分析和实现的代码完成了本例的基本功能,下面我们还要写出程序的WML文件头和执行上述代码的主过程,代码如下:
$view_card .= "</p> </card>";
my $header = qq (
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml.xml">
);
# 执行整个WML卡片的主过程
my $deck = qq(
$header
<wml>
$title_card
$view_card
$all_info_card
</wml>
);
print $q->header('text/vnd.wap.wml');
print $deck;
把以上使用Perl编写的WML代码放在一起(存放数据的文本文件内容除外),就是我们解决的动态显示职员信息的WML应用程序。
|