Пособие по написанию WAP-сайтов

Чтение глав в произвольном порядке

Чтение глав в произвольном порядке

Данная книга начинается с простейших приложений, но совсем не обязательночитать главы книги в представленном порядке. Если вы нашли приложение, которое заинтересовало вас, можете приступать к чтению прямо с этого места. Вызаметите, что при создании каждого приложения представлено пошаговое описание всего процесса. Возможно, вы даже будете говорить себе: "Я уже читалэто". Для того чтобы обеспечить возможность "перепрыгивания" между главами,мы повторяли наиболее важный текст.

Где же будут находиться созданные вами приложения?

Где же будут находиться созданные вами приложения?

После того как вы создадите свои приложения, вы сможете разместить файлыэтих приложений на сайте в Сети, точно так же, как и традиционный файл формата HTML. Позднее, используя свой сотовый телефон для соединения с вашимсайтом, пользователь посредством оборудования для работы с сотовыми телефонами провайдеров получает доступ в Интернет. Далее браузер, расположенныйна телефоне пользователя, просто запрашивает ваш файл формата WML илиHDML с сервера. После того как браузер и сервер завершат операцию скачивания,браузер запустит программу на телефоне пользователя.

Необходимость использования языков WML и HDML

Необходимость использования языков WML и HDML

ЕСЛИ вы внимательно рассмотрите приложения, представленные в каждой изглав, вы обнаружите, что в каждой из них приложение представлено с использованием беспроводного языка разметки WML (Wireless Markup Language), а затем сиспользованием языка разметки для носимых (переносных) устройств HDML(Handheld Devices Markup Language). Так сделано в связи с тем, что некоторые сотовые телефоны поддерживают язык WML, некоторые - язык HDML, а некоторые - итот и другой. Разрабатывая свои приложения, вы должны будете идти двумя путями: сначала используя WML, а затем используя HDML. Позднее, когда пользователь посетит ваш сайт, вы можете для определения типа телефона пользователяиспользовать код, подобный приведенному в Главе 24 "Создавая сайт беспроводных приложений waplib.com". Ваше приложение непосредственно свяжется сбраузером пользователя для загрузки файла формата языка WML или HDML. Приложение А ("Справочник по языку WML") подробно описывает элементы языкаWML. Приложение В ("Справочник по языку HDML") описывает элементы языкаHDML

Пpовepкa нa waplib.com

Пpовepкa нa waplib.com

Для облегчения проверки приложений, описанных в этой книге, используя пакеты для разработки программного обеспечения SDK WAP или совместимый телефон, вы можете посетить сайт waplib.com. Как показано на Рисунок 1.3, когда вы зайдете на сайт, вам будет предложено выбрать представление приложения в формате HDML или WML. Основываясь на вашем выборе, сайт отобразит список доступных приложений, как показано на Рисунок 1.4.

Приложения, требующие языка Perl

Приложения, требующие языка Perl

ЕСЛИ вы внимательно рассмотрите приложения, описанные в этой книге, то заметите, что многие из них используют сценарии (скрипты) на языке Perl для выполнения основной обработки. Например, многие приложения используют сценарии Perl для обработки конструкций if-else для проверки ввода, произведенного пользователем. В последних главах книги вы узнаете, как использоватьWMLScript для выполнения подобной обработки. В настоящее время язык HDML неимеет эквивалента WMLScript и поэтому, чтобы создать эквивалентные приложения на языках WML и HDML, вы часто будете вынуждены использовать язык Perl.Для того чтобы запустить такие приложения на своем компьютере, нужно, чтобыэтот язык был на нем проинсталлирован. В Сети вы сможете найти несколькоадресов, откуда молено скачать интерпретатор языка Perl, подходящий к вашемутипу операционной системы.

Скачивание инструментов для разработкипрограммного обеспечения (SDK)

Скачивание инструментов для разработкипрограммного обеспечения (SDK)

Для написания приложений, поддерживающие протокол WAP и созданных припомощи языков WML и HDML, вы можете использовать любой текстовый редактор по желанию, например, Блокнот из стандартного набора Windows. Если у васнет сотового телефона, поддерживающего протокол WAP для тестирования вашего приложения, вы должны скачать из Сети пакет для разработки программного обеспечения WAP. Пакеты для разработки программного обеспечения называются SDK - Software Development Kit. Посещая соответствующие сайты в Сети, вы найдете, что большинство компаний-производителей сотовых телефоновпредлагают подобные программные пакеты. В таблице 1.1 представлен списокнескольких сайтов, предлагающих подобные пакеты для скачивания.

Сайты, предлагающие для скачивания пакеты для разработки программного обеспечения WAP

Таблица 1.1. Сайты, предлагающие для скачивания пакеты для разработки программного обеспечения WAP













































Компания


Сайт в Интернете




Ericsson


www.ericsson.com




Nokia


www.nokia.com




Openwave Systems


www.openwave.com







В настоящее время не все пакеты для разработки программного обеспечения совместимы друг с другом. Для определенности в этой книге представлены приложения, разработанные для SDK WAP компании Openwave Systems, последнюююверсию которой можно найти по адресу http://developer.openwave.com/download.

Версию 5.0 SDK WAP компании Openwave Systems можно установитьтакже с компакт-диска, прилагаемого к данной книге. Самораспаковывающиеся файлы для установки SDK WAP находятся в папкеSDK_WAP. Дистрибутив SDK WAP для работы в операционной системе Windows 95/98/МЕ содержится в файле Ореп-wave_SDK_WAP_Edition_5.0_Win98Me.exe, а дистрибутив SDK WAPдля работы в операционной системе Windows NT/2000 содержится вфайле Openwave_SDK_WAP_Edition_5.0_WlnNT2000.exe.

Подробнее о приложении WorldTime

Подробнее о приложении WorldTime.hdml

Подробнее о приложении WorldTime.hdml

Так же как и приложение, использующее язык WML, файл WorldTime.hdml отображает текущее время в выбранном городе, используя сотовый телефон. Разни- ца между двумя приложениями в том, что в одном используется язык WML, а вдругом язык HDML. Приведем исходный код файла WorldTime.hdml:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Select Method=Alpha Key=CityName>
<Action Type=Accept Task=GO Method=Post PostData=$(CityName:noesc) Dest=../waplibcgi/WorldTimeHDML.pl>
<Center>World Time<br> <Center>Select City<br>
<CE Value="Honolulu">Honolulu
<CE Value="London">London
<CE Value="Los Angeles">Los Angeles
<CE Value="New York">New York
<CE Value="Paris">Paris
<CE Value="Phoenix">Phoenix
<CE Value="Tokyo">Tokyo
</Choice>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее выражениеMarkable=True сообщает браузеру, что он может установить закладку в исходнойдеке, a TTL=0 свидетельствует о невозможности кэширования.
Для отображения списка городов, из которого необходимо выбрать желаемый,приложение использует элемент . Внутри приложение использует другой элемент для определения имени и расположения сцнария языка Perl. Этот сценарий запускается, когда произведен выбор города иприложение передает ему информацию, которая в нашем случае является названием города.
Далее, для центрирования текста WorldTime и SelectCity приложение используетэлементы
. Напоследок, для определения названий городов используется элемент с применением элемента <СЕ>. Как и в случае с файломформата WML, элемент позволяет пользователю произвести выбор города из списка. После того как пользователь произведет свой выбор, браузер вы- полнит определенные действия, которые в нашем случае заключаются в запускесценария языка Perl.

Подробнее о приложении WorldTime.wml

Подробнее о приложении WorldTime.wml

Когда вы запускаете приложение WorldTime, дека1 WorldTime.wml отображает наэкране телефона названия городов и после произведенного вами выбора городазапускает сценарий языка Perl, который находится в файле WorldTimeWML.pl.Именно этот сценарий (скрипт) и выполняет расчет текущего времени. Приве- дем исходный код деки WorldTime.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" forua="true"/>
</head>
<card id="Choice">
<do type="accept"> <go href="../waplibcgi/WorldTimeWML.pl?$(CityName)" /> </do>
<p align="center">
World Time<br/> Select City<br/>
</p>
<p align="left">
<select name="CityName">
<option value="Honolulu">Honolulu</option> <option value="London">London</option> <option value="Los Angeles">Los Angeles</option> <option value="New York">New York</option> <option value="Paris">Paris</option> <option value="Phoenix">Phoenix</option> <option value="Tokyo">Tokyo</option>
</select>
</p>
</card>
</wml>
Так же как и во всех деках формата WML, первые два ее элемента сообщают брау- зеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.


<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каж- дый раз, когда они будут запрошены. Для этой книги значение нуля было выбра- но для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реаль- ном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Далее, за начальными элементами, в исходном коде определяется единственнаякарта, которая в нашем случае называется Choice. Если вы просмотрите содер- жимое карты браузером, поддерживающим WAP, вы смелеете просмотреть список названий городов, предлагаемых картой и в конечном итоге сделать выборпо своему желанию.


Как было сказано выше, дека WorldTime.wml используется, главным образом, дляотображения названий городов и потом, после выбора пользователем города,для запуска сценария языка Perl, передавая ему при этом название города. Длявыполнения этого действия исходный код использует элемент :

<do type="accept"> <go href="../waplibcgi/WorldTimeWML.pl?$(CityName)" /> </do>

Элемент в нашем случае подключает сценарий языка Perl, передавая емуспециальную опцию интерфейса пользователя.

Если вы внимательно рассмотрите начальное окно приложения, показанное на Рисунок 2.1, то увидите, что браузер отображает заголовок приложения World Time, и

следом предлагает выбрать город: Select City. Для центрирования этих текстовыхсообщений приложение использует тег абзаца <р> с центральным выравниванием, для перевода на следующую строку используется тег
. Далее используеся тег абзаца <р> повторно, только с выравниванием текста по левому краю длявыравнивания названия городов. Внутри элемента <р> используется позволяет пользователю производить выбор из определенного списка городов, устанавливая значение выбранной опции в переменную, доступную во всей деке. В предыдущем элементе для предоставления пользователюсписка штатов, имеющих горнолыжные курорты. Далее, как вы можете видеть,приложение дает указание браузеру загрузить деку определения соответствующего штата.

Подробнее о горнолыжном регионе

Когда пользователь выбирает регион из приложения SkiConditions.hdml, исходный код дает указание браузеру загрузить деку определенного региона. К примеру, когда выбрана опция Rockies, приложение загрузит деку SkiRockies.hdml, исходный код которой приведен ниже:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=GetState>
<Action Type=Accept Label=State> <Action Type=Soft1 Label=Back Task=GO Dest=SkiConditions.hdml>
<Center>Ski Conditions <Line>Select State
<CE Task=GO Dest=SkiAlberta.hdml>Alberta <CE Task=GO Dest=SkiMontana.hdml>Montana <CE Task=GO Dest=SkiWyoming.hdml>Wyoming <CE Task=GO Dest=SkiIdaho.hdml>Idaho <CE Task=GO Dest=SkiUtah.hdml>Utah <CE Task=GO Dest=SkiColorado.hdml>Colorado <CE Task=GO Dest=SkiArizona.hdml>Arizona <CE Task=GO Dest=SkiNewMexico.hdml>New Mexico
</Choice>
</HDML>
Как вы заметили, исходный код использует в работе элемент . Внутри код сперва указывает браузеру на необходимость перезагрузки файлаSkiConditions.hdml, в случае, если пользователь выбрал кнопку Back на дисплеесотового телефона. Далее, код использует элемент <СЕ> для определения спискаштатов, который появляется на дисплее телефона, и для загрузки браузером соответствующей деки при выборе пользователем определенного штата.

Подробнее о горнолыжном штате

Подробнее о горнолыжном штате

Итак, когда пользователь производит выбор горнолыжного штата, исходный кодзагружает деку выбора курортов в этом штате. К примеру, если пользователь выбрал опцию Colorado, код загружает деку SkiColorado.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" forua="true"/>
</head>
<card id="GetArea">
<do type="accept" label="Area"> <noop /> </do>
<do type="options" label="State"> <go href="SkiRockies.wml" /> </do>
<p align="center">
Ski Conditions
</p>
<p align="left" mode="nowrap">
Select Area
<select>
<option onpick="SkiAspen.wml">Aspen</option> <option onpick="SkiBeaver.wml">Beaver Creek</option> <option onpick="SkiBreckenridge.wml">Breckenridge</option> <option onpick="SkiButtermilk.wml">Buttermilk</option> <option onpick="SkiCopper.wml">Copper Mountain</option> <option onpick="SkiCrested.wml">Crested Butte</option> <option onpick="SkiKeystone.wml">Keystone</option> <option onpick="SkiLoveland.wml">Loveland</option> <option onpick="SkiPurgatory.wml">Purgatory</option> <option onpick="SkiSnowmass.wml">Snowmass</option> <option onpick="SkiSteamboat.wml">Steamboat</option> <option onpick="SkiTelluride.wml">Telluride</option> <option onpick="SkiVail.wml">Vail</option> <option onpick="SkiWinter.wml">Winter Park</option>

Подробнее о горнолыжном штате

Когда пользователь производит выбор горнолыжного штата, исходный код даетуказание браузеру загрузить деку определенного штата. К примеру, если пользователь выбрал опцию Colorado, приложение загружает деку SkiColorado.hdml, содержимое которой приведено ниже:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=GetArea Method=Alpha>
<Action Type=Accept Label=Area> <Action Type=Soft1 Label=State Task=GO Dest=SkiRockies.hdml>
<Center>Ski Conditions <Line>Select Area
<CE Task=GO Dest=SkiAspen.hdml>Aspen <CE Task=GO Dest=SkiBeaver.hdml>Beaver Creek <CE Task=GO Dest=SkiBreckenridge.hdml>Breckenridge <CE Task=GO Dest=SkiButtermilk.hdml>Buttermilk <CE Task=GO Dest=SkiCopper.hdml>Copper Mountain <CE Task=GO Dest=SkiCrested.hdml>Crested Butte <CE Task=GO Dest=SkiKeystone.hdml>Keystone <CE Task=GO Dest=SkiLoveland.hdml>Loveland <CE Task=GO Dest=SkiPurgatory.hdml>Purgatory <CE Task=GO Dest=SkiSnowmass.hdml>Snowmass <CE Task=GO Dest=SkiSteamboat.hdml>Steamboat <CE Task=GO Dest=SkiTelluride.hdml>Telluride <CE Task=GO Dest=SkiVail.hdml>Vail <CE Task=GO Dest=SkiWinter.hdml>Winter Park
</Choice>
</HDML>
Исходный код использует в работе элемент . Внутри используется элемент <СЕ> для определения списка курортов, который появляется надисплее телефона, и для загрузки браузером соответствующей деки при выборепользователем определенного курорта.


</select>

</p>

</card>

</wml>

Как вы можете видеть, файл определяет единственную карту, которая в нашемслучае называется GetArea. Первый элемент предписывает браузеру не производить действия () с опцией accept и изменить стандартную надписьОК на Area (Область) на кнопке подтверждения (accept), которая появляется насотовом телефоне.

Далее, исходный код сообщает браузеру, что надо перезагрузить декуSkiRokies.wml, если пользователь выберет опцию State (Штат), которая появляется на его телефоне. Если, например, пользователь выбрал неправильный штат,он может быстро возвратится к списку штатов выбором кнопки State.

Наконец, в деке используется оператор для показа списка регионов пользователю. Внутри , он отобразит одну строку для каждойопции, определенной внутри этого элемента. Если для показа списка кинотеатров пользователю. Внутри для отображения списка доступных валют. После того как пользовательпроизвел выбор желаемой валюты, происходит переход к соответствующей карте, находящейся внутри этой же деки. К примеру, если выбрана валюта США, висходном коде происходит переход к карте GetUSDollar. Внутри этой карты используется элемент для ввода суммы валюты, и затем запускается сценарий CurrencyConvertWML.pl, который и производит непосредственно вычисления. Этот сценарий языка Perl содержит следующий исходный код:

#!/usr/bin/perl

$Buffer = $ENV{'QUERY_STRING'};

@data = split(/&/, $Buffer);

$Currency = $data[0]; $Value = $data[1];

$DollarToEuro = .971032; $DollarToPound = .607327; $DollarToYen = 105.555;

$EuroToDollar = 1.02982; $EuroToPound = .625449; $EuroToYen = 108.702;

$PoundToDollar = 1.64649; $PoundToEuro = 1.59887; $PoundToYen = 173.814;

$YenToDollar = .00947277; $YenToEuro = .00919888; $YenToPound = .00575343;

if ($Currency eq "USDollar") { $USDollar = $Value; $Euro = (int(($Value * $DollarToEuro) * 100)) / 100; $UKPound = (int(($Value * $DollarToPound) * 100)) / 100; $JapanYen = (int(($Value * $DollarToYen) * 100)) / 100; }


elsif ($Currency eq "Euro") { $USDollar = (int(($Value * $EuroToDollar) * 100)) / 100; $Euro = $Value; $UKPound = (int(($Value * $EuroToPound) * 100)) / 100; $JapanYen = (int(($Value * $EuroToYen) * 100)) / 100; }

elsif ($Currency eq "UKPounds") { $USDollar = (int(($Value * $PoundToDollar) * 100)) / 100; $Euro = (int(($Value * $PoundToEuro) * 100)) / 100; $UKPound = $Value; $JapanYen = (int(($Value * $PoundToYen) * 100)) / 100; }

elsif ($Currency eq "JapanYen") { $USDollar = (int(($Value * $YenToDollar) * 100)) / 100; $Euro = (int(($Value * $YenToEuro) * 100)) / 100; $UKPound = (int(($Value * $YenToPound) * 100)) / 100; $JapanYen = $Value; }

$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card id=\"Result\">

<do type=\"accept\" label=\"Done\"> <go href=\"../CurrencyConvert/CurrencyConvert.wml\" /> </do>

<p align=\"center\">

Currency Converter

</p>

<p align=\"left\" mode=\"nowrap\">

<table align=\"left\" columns=\"2\">

<tr> <td>US Dollars:</td> <td>$USDollar</td> </tr>

<tr> <td>Euro:</td> <td>$Euro</td> </tr>

<tr> <td>UK Pounds:</td> <td>$UKPound</td> </tr>

<tr> <td>Japan Yen:</td> <td>$JapanYen</td> </tr>

</table>


</p>

</card>

</wml>";

print $Deck;

В нашем случае сценарий использует для конвертирования фиксированные коэфициенты. В реальности вам придется, скорее всего, работать с изменяющимися коэфициентами для вычислений конвертирования.

Запускаясь, сценарий использует параметр $ENV для получения указателя на список параметров (приложение передает сценарию тип валюты и сумму денег какпараметры). Далее, исходный код использует функцию разделения split (/&/,$Ви££ег)для анализа переданного, употребляя символ & (амперсант) как разделитель. А именно, значение типа валюты присваивается элементу массиваdata[0], а значение суммы - элементу массива data[l]. Далее, значение этихэлементов массива (тип валюты и сумма) присваивается переменным $ Currencyи $Value.

Вслед за этими действиями в исходном коде значения коэфициентов конвертирования присваиваются определенным переменным, которые затем сценарийиспользует в процессе вычислений. Как говорилось ранее, вы можете использовать значения этих коэфициентов из реальных источников, в отличие от приведенных здесь фиксированных значений.

Далее, сценарий обращается к серии конструкций if-else для определения типапреобразования. Для уменьшения ошибок округления, в исходном коде результатпреобразования умножается на 100 и переводится в целочисленный тип, используя функцию int. Затем полученный результат делится на 100 для того, чтобы получить обратно корректный результат.

Следом за преобразованием сценарий создает новую деку формата WML, для тогочтобы браузер отобразил результат вычислений. Для лучшего отображения полученного результата типы валют и значения выводятся в таблицу из двух столбцов.

Подробнее о приложении SmartHouse

Подключение к интерфейсу"Интеллектуального" Дома

Рисунок 6.1. Подключение к интерфейсу"Интеллектуального" Дома

Подключение к интерфейсу

Подробнее о приложении SmartHouse.hdml

Подробнее о приложении SmartHouse.hdml

Подобно приложению SmartHouse.wml, приложение SmartHouse.hdml отображаетсообщение, извещающее пользователя о том, что он подсоединен к интерфейсудома, и второе сообщение, которое приглашает подтвердить, хочет ли он работать далее. Файл SmartHouse.hdml содержит следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Start>
<Action Type=Accept Task=GO Method=Post PostData=-1&-1&-1&-1&-1 Dest=../waplibcgi/UpdateHouseHDML.pl>
<Center>Smart House<br> <Line>Connected.<br><br> Get current status?
</Display>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам) отом, какая версия языка HDML используется приложением. Далее, выражениеMarkable=True сообщает браузеру, что он может установить закладку в исходнойдеке, a TTL=0 сообщает о невозможности кэширования.
Для отображения сообщений приложение использует элемент . Внутри используется элемент для определения имени и места
нахождения сценария, который приложение запустит, как только пользователь вответ на запрос выберет продолжение работы. Как вы видите, приложение передает -1 в качестве значения параметра сценарию языка Perl, что говорит о первом его запуске и необходимости сгенерировать случайную последовательностьустановок ON/OFF. Для имитирования оборудования в доме используется сценарий языка Perl UpdateHouseHDML.pl, содержимое которого подобно сценарию UpdateHouseWML.pl, заисключением двух значительных отличий. Во-первых, приложение создает новую деку формата HDML, используя элементы и <СЕ> для отображениянового состояния и установки последующих изменений, как показано ниже:
$Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=House>
<Action Type=Accept Label=OnOff>
<Center>Smart House
$CEBedroom $CEKitchen $CELiving $CEOffice $CEOutside
</Choice>
</HDML>";
print $Deck;
Второе отличие заключается в формировании элементов <СЕ>. Когда запускаетсясценарий UpdateHouseHDML.pl, ему в качестве аргумента передается случайноечисло. Это присходит в связи с особенностями работы системы кэшированияпамяти. Как вы видите, каждый раз, когда пользователь производит выбор, сценарий UpdateHouseHDML.pl вызывает сам себя для выполнения обработки данных. Даже несмотря на установленное в ноль значение TTL, которое показывает,что дека не может быть никогда перезагружена из кэша, когда дека вызывает самасебя, она всегда перезагружается из кэша. Посредством присвоения случайногозначения аргументу, браузер интерпретирует полученную информацию как другую деку и загружает ее с сервера.


Подробнее о приложении SmartHouse.wml

Подробнее о приложении SmartHouse.wml

При запуске пользователем приложения SmartHouse, загружается дека из файла SmartHouse.wml. После загрузки на дисплее появляется сообщение, сигнализирующее о подключении к интерфейсу дома, и далее, второе сообщение, желаетли пользователь продолжать начатые действия. Если пользователь собираетсяэто делать, приложение загружает сценарий языка Perl UpdateHouseWML.pl, передавая ему параметры, содержащие информацию о текущих установках в доме.Приведенный ниже исходный код отображает содержимое деки SmartHouse.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" forua="true"/>
</head>
<card id="SmartHouse">
<do type="accept"> <go href="../waplibcgi/UpdateHouseWML.pl?-1& -1&-1&-1&-1" /> </do>
<p align="center">
Smart House<br/>
</p>
<p align="left" mode="nowrap">
Connected.<br/><br/> Get current status?
</p>
</card>
</wml>
Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.
<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

В деке используется тег абзаца <р> для вывода заголовка приложения, сообщенияо подключении пользователя к дому и запроса на продолжение действий. Еслипользователь посчитает нужным продолжить начатые действия, в деке используется элемент для запуска сценария языка Perl:

<head>

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

</head>

Подробнее о сценарии языка Perl UpdateHouseWML.pl

Подробнее о сценарии языка Perl UpdateHouseWML.pl

В идеале приложение SmartHouse соединяется с оборудованием, находящимсявнутри вашего дома. В нашем случае это оборудование симулирует сценарий языка Perl. Этот сценарий содержит следующий исходный код:
#!/usr/bin/perl
$Buffer = $ENV{'QUERY_STRING'};
@data = split(/&/, $Buffer);
$Bedroom = $data[0]; $Kitchen = $data[1]; $Living = $data[2]; $Office = $data[3]; $Outside = $data[4];
if ($Bedroom eq -1) { srand; $Bedroom = rand(); $Bedroom = int ($Bedroom + .5);
$Kitchen = rand(); $Kitchen = int ($Kitchen + .5);
$Living = rand(); $Living = int ($Living + .5);
$Office = rand(); $Office = int ($Office + .5);
$Outside = rand(); $Outside = int ($Outside + .5); }
if ($Bedroom eq 0) { $OptionBedroom = "<option onpick=\"UpdateHouseWML.pl?1\& $Kitchen\&$Living\&$Office\&$Outside\">"; $OptionBedroom = $OptionBedroom . "Bedroom is OFF</option>"; } else { $OptionBedroom = "<option onpick=\"UpdateHouseWML.pl?0\& $Kitchen\&$Living\&$Office\&$Outside\">"; $OptionBedroom = $OptionBedroom . "Bedroom is ON</option>"; }
if ($Kitchen eq 0) { $OptionKitchen = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&1\&$Living\&$Office\&$Outside\">"; $OptionKitchen = $OptionKitchen . "Kitchen is OFF</option>"; } else { $OptionKitchen = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&0\&$Living\&$Office\&$Outside\">"; $OptionKitchen = $OptionKitchen . "Kitchen is ON</option>"; }
if ($Living eq 0) { $OptionLiving = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&1\&$Office\&$Outside\">"; $OptionLiving = $OptionLiving . "Living room is OFF</option>"; } else { $OptionLiving = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&0\&$Office\&$Outside\">"; $OptionLiving = $OptionLiving . "Living room is ON</option>"; }

if ($Office eq 0) { $OptionOffice = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&$Living\&1\&$Outside\">"; $OptionOffice = $OptionOffice . "Office is OFF</option>"; } else { $OptionOffice = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&$Living\&0\&$Outside\">"; $OptionOffice = $OptionOffice . "Office is ON</option>"; }

if ($Outside eq 0) { $OptionOutside = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&$Living\&$Office\&1\">"; $OptionOutside = $OptionOutside . "Outside is OFF</option>"; } else { $OptionOutside = "<option onpick=\"UpdateHouseWML.pl? $Bedroom\&$Kitchen\&$Living\&$Office\&0\">"; $OptionOutside = $OptionOutside . "Outside is ON</option>"; }

$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card id=\"House\">

<do type=\"accept\" label=\"OnOff\"> <noop /> </do>

<p align=\"center\">

Smart House

</p>

<p align=\"left\" mode=\"nowrap\">

<select>

$OptionBedroom $OptionKitchen $OptionLiving $OptionOffice $OptionOutside

</select>

</p>

</card>

</wml>";

print $Deck;

Как было сказано выше, когда приложение вызывает сценарий языка Perl, емупередаются параметры, которые соответствуют установкам в доме.


Когда сценарий начинает выполняться, он использует функцию $ENV для получения указателя на список параметров. Далее, исходный код использует функцию разделенияsplit (/&/, $Buffer) для анализа переданного, используя символ & (амперсанд)как разделитель и передавая значения массиву с именем gdata. В итоге в сценарии присваиваются значения элементов массива переменным, которые будут использоваться в процессе работы:

$Buffer = $ENV{'QUERY_STRING'};

@data = split(/&/, $Buffer);

$Bedroom = $data[0]; $Kitchen = $data[1]; $Living = $data[2]; $Office = $data[3]; $Outside = $data[4];

Далее, в исходном коде проверяется значение переменной $Bedroom. Если значение этой переменной равно -1, которое означает, что приложение вызываетсценарий в первый раз и сценарий должен сгенерировать случайные значенияустановок ON/OFF (ВКЛ/ВЫКЛ) бытовой техники в доме.

Если приложение вызывает сценарий не в первый раз, сценарий обрабатываетпоследовательность конструкций if-else, определяя, производятся ли пользователем изменения в установках, и если да, то какое значение (ON или OFF) имеет на данный момент определенная установка (сценарий может также менять этизначения).

После этого сценарий с новыми значениями установок создает еще одну карту,используя элемент print. Браузер отображает конечный результат установок надисплее сотового телефона.

Подробнее о приложении StockQuote

Отображение списка доступных символов акций

Рисунок 7.3. Отображение списка доступных символов акций

Отображение списка доступных символов акций

Подробнее о приложении StockQuote.hdml

Подробнее о приложении StockQuote.hdml

Как и приложение формата WML, файл StockQuote.hdml предлагает пользователюввести символ акции. Далее приложение загружает сценарий языка Perl, которыйопределяет, какой символ был введен, и затем отображает информацию о выбранной акции. Файл StockQuote.hdml имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Entry Name=Stock Format=*X Key=Symbol Default="">
<Action Type=Accept Task=GO Method=Post PostData=$(Symbol) Dest="../waplibcgi/StockQuoteHDML.pl">
<Center>Stock Quotes <BR><BR>Symbol: <BR>(* for all)
</Entry>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке,a TTL=0 свидетельствует о невозможности кэширования.
Как и дека формата WML, дека формата HDML использует переменную с именемSymbol для отслеживания имени введенного пользователем символа. Для вводаимени символа, приложение использует элемент :
<Entry Name=Stock Format=*X Key=Symbol Default="">
Формат *х позволяет пользователю ввести любое число символов, чисел и буквверхнего регистра.
После ввода пользователем имени символа или звездочки (*), приложение использует элемент для загрузки сценария языка Perl StockQuoteHDML.pl,передавая ему значение переменной Symbol.

Подробнее о приложении StockQuote.wml

Подробнее о приложении StockQuote.wml

Когда пользователь запускает приложение StockQuote, дека StockQuote.wml запрашивает у пользователя ввода символа акции. Далее, основываясь на выборепользователя, подключается сценарий языка Perl, находящийся в файлеStockQuoteWML.pl. После этого сценарий определяет символ, введенный пользователем, и отображает деку формата WML, соответствующую выбранной акции.Дека StockQuote.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" forua="true"/>
</head>
<card id="Quote" title="Stock Quotes">
<onevent type="onenterforward">
<refresh> <setvar name="Symbol" value="" /> </refresh>
</onevent>
<onevent type="onenterbackward">
<refresh> <setvar name="Symbol" value="" /> </refresh>
</onevent>
<do type="accept"> <go href="../waplibcgi/StockQuoteWML.pl?$(Symbol)" /> </do>
<p align="center">
Stock Quotes<br/>
</p>
<p align="left" mode="nowrap">
Symbol:<br/> (* for all)<br/>
<input name="Symbol" maxlength="5" title="Symbol" type="text" format="*X" />
</p>
</card>
</wml>
Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.


<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом. <ой \

Далее, за первыми элементами в деке определяется единственная карта, котораяв нашем случае называется Quote. Как вкратце отмечалось выше, основная задачадеки StockQuote.wml - это приглашение пользователю на ввод символа акции, азатем вызов сценария языка Perl для отображения информации о выбранной акции.


Для отслеживания имени символа приложение использует переменную Symbol.Обратите внимание на два элемента в исходном коде недалеко от начала деки. Выувидите два элемента , которые очищают значение переменной Symbol(символ акции), перед тем как пользователь введет новый символ акции.

Элементы обработки событий удаляют любое существующее значениепеременной Symbol. Обработка этих событий выполняется перед тем, как пользователем будет введена какая-либо информация. Пакет для разработки про

граммного обеспечения (SDK) запоминает значения переменных при каждомпоследующем запуске программы. В первом элементе с использованием выражения type="OnEnterForward" удаляется значение переменной, когдапрограмма запускается. Второе выражение type="oneenterbackward" свидетельствует об удалении значения переменной, если пользователь нажал кнопку Back(Назад). Элемент обновляет переменные и вид экрана, если какая-либо из переменных отображается в данный момент.

Для передачи введенной пользователем информации в переменную, приложениеиспользует элемент :

<input name="Symbol" maxlength="5" title="Symbol" type="text" format="*X" />

Элемент определяет имя переменной, заголовок, который браузер будетотображать на дисплее телефона для этой переменной, максимальное число символов в переменной (в нашем случае 5), тип данных переменной (text) и форматпеременной. Формат *х позволяет переменной иметь длину не более maxlenthсимволов, цифр или букв верхнего регистра. \

Далее, если вы обратите внимание на экран приложения, показанный на Рисунок 7.1,приложение выводит заголовок StockQuotes и приглашение для ввода символа.Здесь можно ввести звездочку (*) в ответ на приглашение (* for all - * для всех). Вэтом случае приложение отобразит меню символов всех акций из своей базыданных. Для отображения этих текстовых сообщений приложение используеттег абзаца <р> с соответствующим выравниванием и тег
для перехода наследующую строку.После того как желаемый символ акции будет введен пользователем, приложение подключает сценарий языка Perl StockQuoteWML.pl, описанный ниже.

Подробнее о сценарии языка Perl StockQuoteHDML.pl

Подробнее о сценарии языка Perl StockQuoteHDML.pl

Итак, когда пользователь вводит имя символа акции в файле StockQuote.hdml,приложение передаст данные сценарию StockQuoteHDML.pl, который, используяпоследовательность конструкций if-else, определяет выбранную пользователемакцию. Очевидно, что содержимое сценария StockQuoteHDML.pl в целом аналоично содержимому файла StockQuoteWML.pl за исключением того, что первыйиспользует в своей работе деки формата HDML.
Аналогично, когда пользователь на запрос имени символа вводит МОК, сценарийязыка Perl загружает файл NOK.hdml, исходный код которого приведен ниже:
<HDML Version=3.0 TTL=0>
<Display>
<ACTION Type=Accept Task=Prev Vars=Symbol=>
<Center>Stock Quotes<BR>
<Line>NOK<TAB>Nokia Corp <Line>Last:<TAB>141 3/4 <Line>Change:<TAB>+1 3/4 <Line>Volume:<TAB>4.074 mil <Line>Open:<TAB>138 <Line>High:<TAB>143 <Line>Low:<TAB>138 <Line>52 High:<TAB>151.62 <Line>52 Low:<TAB>47.81
</Display>
</HDML>
Для отображения информации о выбранной акции дека формата HDML простоиспользует элемент . Для изменения информации о котировке акций необходимо внести изменения в содержимое соответствующих дек. В идеале вашеприложение должно обращаться к базе данных на сервере для считывания необходимой информации о котировках акций в режиме реального времени.
Если пользователем введено неправильное имя символа, сценарий языка Perl загружает деку BadSYM.hdml, которая имеет следующий исходный код:
<HDML Version=3.0 TTL=0>
<Display>
<ACTION Type=Accept Task=GO Dest=../StockQuote/StockQuote.hdml Vars=Symbol=>
<Center>Stock Quotes<BR>
<BR>Unknown stock symbol. Try again. <BR><BR>For this demo the only valid symbols are: <BR>AIRO <BR>NOK <BR>PCS <BR>PHCM


</Display>

</HDML>

В этой деке элемент используется для отображения сообщения обошибке и вывода возможных значений имен символов. Вдобавок к этому, исходный код использует для удаления неправильно введенного имени символа и возврата к деке StockQuote.hdml, если пользователь нажмет кнопку подтверждения выбора (ОК).

В заключение, если пользователь введет звездочку (*) для просмотра списка всехвозможных имен символов, сценарий языка Perl загрузит деку ShowAll.hdml, исходный код которой приведен ниже:

<HDML Version=3.0 TTL=0>

<Choice>

Known Symbols<BR>

<CE Task=GO Dest=../StockQuote/AIRO.hdml Label=AIRO>AIRO <CE Task=GO Dest=../StockQuote/NOK.hdml Label=NOK>NOK <CE Task=GO Dest=../StockQuote/PCS.hdml Label=PCS>PCS <CE Task=GO Dest=../StockQuote/PHCM.hdml Label=PHCM>PHCM

</Choice>

</HDML>

Используя элемент , дека сперва отобразит список возможных для выбора символов, которые представлены в ней с помощью элементов <СЕ>. Далее определяет, какой из символов введен пользователем, Если, к примеру,пользователь выберет символ NOK, автоматически загрузится дека NOK.hdml.


Подробнее о сценарии языка Perl StockQuoteWML.pl

Подробнее о сценарии языка Perl StockQuoteWML.pl

Как было сказано выше, каждый раз, когда пользователь вводит символ акции,приложение вызывает сценарий языка Perl, который и отображает информациюо выбранной акции. На самом деле для отображения информации о конкретнойакции сценарий загружает другой файл, относящийся непосредственно к выбранной акции. Например, для отображения информации об акциях Nokia (символ NOK), сценарий загружает файл NOK.wml. Сценарий StockQouteWML.pl имеетследующий исходный код:
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";
$Buffer = $ENV{'QUERY_STRING'};
if ($Buffer eq "AIRO") { $FileName = "../StockQuote/AIRO.wml"; } elsif ($Buffer eq "PHCM") { $FileName = "../StockQuote/PHCM.wml"; } elsif ($Buffer eq "PCS") { $FileName = "../StockQuote/PCS.wml"; } elsif ($Buffer eq "NOK") { $FileName = "../StockQuote/NOK.wml"; } elsif ($Buffer eq "*") { $FileName = "../StockQuote/ShowAll.wml"; } else { $FileName = "../StockQuote/BadSYM.wml"; }
open (StockInfo, $FileName);
while (<StockInfo>) { print; }
close (StockInfo);
В нашем случае сценарий распознает только несколько символов. В реальномприложении вы не сможете разместить информацию о каждой из акций в отдельной карте формата WML. Вы будете должны размещать информацию в базеданных. После этого сценарий должен извлечь нужную информацию из базыданных и создать карту с интересующими вас сведениями в режиме реальноговремени.
Первая строка сценария представляет собой комментарий, сообщающий интерпретатору командной строки, где находится интерпретатор языка Perl. Во второйстроке сценарий помещает информацию для браузера (который перехватываетвывод сценария), какой тип данных будет отображаться. В третьей строке сценарий выделяет параметр, который ему передает исходная дека. В нашем случаеэто имя символа:
$Buffer = $ENV{'QUERY_STRING'};
Далее, сценарий использует последовательность конструкций if-else для определения имени символа.


Например, если пользователь выбрал символ NOK, сценарий будет использовать деку из файла NOK.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" forua="true"/>

</head>

<card id="Quote">

<do type="accept" label="Back"> <prev /> </do>

<p align="center">

Stock Quotes<br/>

</p>

<p align="left" mode="nowrap">

<table align="left" columns="2">

<tr> <td>NOK</td> <td>Nokia Corp</td> </tr>

<tr> <td>Last:</td> <td>141 3/4</td> </tr>

<tr> <td>Change:</td> <td>+1 3/4</td> </tr>

<tr> <td>Volume:</td> <td>4.074 mil</td> </tr>

<tr> <td>Open:</td> <td>138</td> </tr>

<tr> <td>High:</td> <td>143</td> </tr>

<tr> <td>Low:</td> <td>138</td> </tr>

<tr> <td>52 High:</td> <td>151.62</td> </tr>

<tr> <td>52 Low:</td> <td>47.81</td> </tr>

</table>

</p>

</card>

</wml>

Как видите, в деке жестко указана информация об акциях.


Это значит, что дляизменения информации о них, вам (или другому программисту) необходимо внести изменения непосредственно в файл. В идеале приложение должно получатьэти значения из базы данных, содержащей реальную информацию об акциях наданный промежуток времени и затем использовать эту информацию для создания новых дек в процессе работы.

Для облегчения восприятия выходной информации она организуется в таблицу.Как было сказано выше, если пользователь вводит звездочку в ответ на запрос овводе символа акции, приложение отобразит список всех доступных символов,как показано на Рисунок 7.3. Чтобы обработать введенную звездочку, сценарий языкаPerl вызывает деку из файла ShowAll.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" forua="true"/>

</head>

<card>

<do type="accept"> <go href="../StockQuote/StockQuote.wml"/> </do>

<p align="left" mode="nowrap">

Known Symbols<br/>

<a href="../StockQuote/AIRO.wml" title="AIRO">AIRO</a> <a href="../StockQuote/NOK.wml" title="NOK">NOK</a> <a href="../StockQuote/PCS.wml" title="PCS">PCS</a> <a href="../StockQuote/PHCM.wml" title="PHCM">PHCM</a>

</p>

</card>

</wml>

В деке используется тег <а> для отображения имен символов и определения, какую деку загружать после того как пользователь ввел выбранный символ.

Так как пользователь имеет возможность самостоятельного ввода имени символаакции, возможны ошибки при наборе имени или набор имени, несуществующегов базе данных приложения.


Когда сценарий не может определить введеное имя(внутри последовательности конструкций if-else), он загружает деку из файлаBadSYM.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" forua="true"/>

</head>

<card>

<do type="accept"> <go href="../StockQuote/StockQuote.wml"/> </do>

<p align="center">

Stock Quotes<br/>

</p>

<p align="left" mode="wrap">

Unknown stock symbol. Try again. <br/><br/>For this demo the only valid sybmols are: <br/>AIRO <br/>NOK <br/>PCS <br/>PHCM

</p>

</card>

</wml>

Как вы видите, файл BadSYM.wml отображает сообщение для пользователя о том,что введенный символ неверен. Далее отображается список доступных имен

символов.

Подробнее о приложении PhoneBook

Подробнее о приложении PhoneBook.hdml

Подробнее о приложении PhoneBook.hdml

Как и приложение формата WML, дека PhoneBook.hdml позволяет пользователюнайти и автоматически дозвониться по номеру, хранящемуся в телефонном справочнике в режиме "онлайн". Эта дека имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Main Method=Alpha>
<Center>Phone Book<BR>
<CE Task=GO Dest=PhoneBookAF.hdml Label=A-F>A - F <CE Task=GO Dest=PhoneBookGM.hdml Label=G-M>G - M <CE Task=GO Dest=PhoneBookNS.hdml Label=N-S>N - S <CE Task=GO Dest=PhoneBookTZ.hdml Label=T-Z>T - Z
</Choice>
</HDML>
Первый элемент сообщает браузеру (или другим программистам), какая версияязыка HDML используется приложением. Далее выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке, a TTL=0 свидетельствует о невозможности кэширования деки.
Для отображения списка диапазонов букв, из совокупности которых пользователь производит свой выбор, приложение использует элемент . Внутри используются элементы <СЕ> для определения деки формата HDML, которую будет загружать приложение после того как пользователь произведет выбор диапазона букв.
Если, к примеру, пользователь выберет [A-F], приложение загрузит деку PhoneBookAF.hdml, которая имеет следующий исходный код:
<HDML Version=3.0 TTL=0>
<Choice Name=AF Method=Alpha>
<Action Type=Soft1 Task=GO Dest=PhoneBook.hdml Label=Back>
<Center>Phone Book<BR> <Center>(A - F)
<CE Task=GO Dest=#A Label=A>A <CE Task=GO Dest=#B Label=B>B <CE Task=GO Dest=#C Label=C>C <CE Task=GO Dest=#D Label=D>D <CE Task=GO Dest=#E Label=E>E <CE Task=GO Dest=#F Label=F>F
</Choice>
<Choice Name=A Key=choice Method=Alpha>
<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>


<Center>- - A - -

<CE Task=Call Number="1-800-272-3623" >Adobe Acrobat Support <CE Task=Call Number="1-206-622-5500" >Aldus Corporation

</Choice>

<Choice Name=B Key=choice Method=Alpha>

<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>

<Center>- - B - -

<CE Task=NOOP> <!-- Remove this line if you have entries for this letter -->

</Choice>

<Choice Name=C Key=choice Method=Alpha>

<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>

<Center>- - C - -

<CE Task=Call Number="1-613-728-8200" >Corel Corporation

</Choice>

<Choice Name=D Key=choice Method=Alpha>

<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>

<Center>- - D - -

<CE Task=NOOP> <!-- Remove this line if you have entries for this letter -->

</Choice>

<Choice Name=E Key=choice Method=Alpha>

<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>

<Center>- - E - -

<CE Task=NOOP> <!-- Remove this line if you have entries for this letter -->

</Choice>

<Choice Name=F Key=choice Method=Alpha>

<Action Type=Soft1 Task=GO Dest=#AF Label=Back> <Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>

<Center>- - F - -

<CE Task=NOOP> <!-- Remove this line if you have entries for this letter -->

</Choice>

</HDML>

После загрузки дека использует элементы и <СЕ> для отображения буквА, В, С, D, Е и F вертикально на дисплее сотового телефона пользователя.В зависимости от выбора пользователя, приложение обращается к локальной карте,которая содержит информацию, касающуюся выбранной буквы.

Внутри каждой из карт приложение обеспечивает выполнение двух действий.Первым действием является предоставление пользователю возможности вернуться к предыдущей карте, в нашем случае к карте диапазона [A-F]. Вторым действием является предоставление пользователю возможности автоматически сделать звонок по выбранному номеру (приложение запоминает этот номер в переменной Choice):

<Action Type=Accept Icon=phone1 Label=Call Task=Call Number=$choice>


Подробнее о приложении PhoneBook.wml

Подробнее о приложении PhoneBook.wml

Когда пользователь запускает приложение PhoneBook, дека PhoneBook.wml отображает диапазоны букв. Далее по выбору пользователя загружается карта, относящаяся к выбранному диапазону. Дека PhoneBook.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" forua="true"/>
</head>
<card id="Main">
<p align="center">
<b>Phone Book</b><br/> <a href="PhoneBookAF.wml" title="A - F">A - F</a> <a href="PhoneBookGM.wml" title="G - M">G - M</a> <a href="PhoneBookNS.wml" title="N - S">N - S</a> <a href="PhoneBookTZ.wml" title="T - Z">T - Z</a>
</p>
</card>
</wml>
Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.
<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеру

WAR, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Далее, за первыми элементами, в деке определяется единственная карта, котораяв нашем случае называется Main. Пользователь может прокручивать предложенный ему список диапазонов букв в окне браузера телефона, выбирая в конечномитоге желаемый диапазон. Для организации этого выбора в деке используетсясерия тегов <а>, каждая из которых относится к определенному диапазону. Если,к примеру, пользователь выбирает [A-F], то загружается дека PhoneBookAF.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" forua="true"/>

</head>

<card id="AF">

<do type="options" label="Back"> <go href="PhoneBook.wml"/> </do>

<p align="center">

<b>Phone Book<br/> (A - F)</b><br/> <a href="#A" title="A">A</a> <a href="#B" title="B">B</a> <a href="#C" title="C">C</a> <a href="#D" title="D">D</a> <a href="#E" title="E">E</a> <a href="#F" title="F">F</a>

</p>

</card>

<card id="A">

<do type="options" label="Back"> <go href="#AF"/> </do>

<p align="center">

<b>- - A - -</b><br/>

</p>

<p>

Adobe Acrobat Support<br/> <a href="wtai://wp/mc;18002723623" title="Call">1-800-272-3623</a> Aldus Corporation<br/> <a href="wtai://wp/mc;12066225500" title="Call">1-206-622-5500</a>

</p>

<p align="center">

..........

</p>

</card>

<card id="B">

<do type="options" label="Back"> <go href="#AF"/> </do>

<p align="center">

<b>- - B - -</b><br/>

</p>

</card>

<card id="C">

<do type="options" label="Back"> <go href="#AF"/> </do>


<p align="center">

<b>- - C - -</b><br/>

</p>

<p>

Corel Corporation<br/> <a href="wtai://wp/mc;16137288200" title="Call">1-613-728-8200</a>

</p>

<p align="center">

..........

</p>

</card>

<card id="D">

<do type="options" label="Back"> <go href="#AF"/> </do>

<p align="center">

<b>- - D - -</b><br/>

</p>

</card>

<card id="E">

<do type="options" label="Back"> <go href="#AF"/> </do>

<p align="center">

<b>- - E - -</b><br/>

</p>

</card>

<card id="F">

<do type="options" label="Back"> <go href="#AF"/> </do>

<p align="center">

<b>- - F - -</b><br/>

</p>

</card>

</wml>

Как вы видите, карта начинается с отображения в столбик букв А, В, С, D, Е и F надисплее сотового телефона с помощью тега <а>. Далее, основываясь на выборепользователя, происходит переход к локальной карте, которая находится внутриэтой деки. Приложение отображает локальную карту, используя перед ее именемсимвола фунта [#]. Внутри каждой карты приложение использует ссылку Back (Назад), которая позволит пользователю вернуться к предыдущей карте, в нашем случае - к карте AF.

Подробнее о приложении WapPage

Обзор общего резюме сообщения

Рисунок 9.4. Обзор общего резюме сообщения

Обзор общего резюме сообщения


Для того чтобы запустить приложение WapPage из своей собственной системы, вы должны использовать операционную систему Unixили Linux.

Передача сообщения с сайта Интернет

Рисунок 9.5. Передача сообщения с сайта Интернет

Передача сообщения с сайта Интернет

После того как пользователь введет необходимую для сообщения информацию инажмет кнопку Send, файл формата HTML пошлет данные сценарию языка Perl,который, обработав эту информацию, посредством электронной почты перешлет сообщение в центр обработки сообщений PCS Sprint. Файл WebPage.htmlимеет следующий исходный код:
<html>
<head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta http-equiv="Content-Language" content="en-us"> <title>Web Page</title> </head>
<body> <p align="center"><font face="Arial" size="6">Web Page</font></p> <p align="center"><font face="Arial" >(Page a Sprint PCS phone)</font></p>
<form method="POST" action="http://waplib.com/waplibcgi/ WebPage.pl">
<table border="0" width="43%"> <tr> <td width="30%"><font face="Arial" size="4" ><b>Reply-To:</b></font></td> <td width="70%"> <input type="text" name="ReplyTo1" size="3" maxlength="3"> <font face="Arial" size="4">- </font> <input type="text" name="ReplyTo2" size="3" maxlength="3"> <font face="Arial" size="4">-</font> <input type="text" name="ReplyTo3" size="3" maxlength="4"></td> </tr> <tr> <td width="30%"> </td> <td width="70%"></td> </tr> <tr> <td width="30%"><font face="Arial" size="4" ><b>Send To:</b></font></td> <td width="70%"> <input type="text" name="SendTo1" size="3" maxlength="3"> <font face="Arial" size="4">- </font> <input type="text" name="SendTo2" size="3" maxlength="3"> <font face="Arial" size="4">-</font> <input type="text" name="SendTo3" size="3" maxlength="4"></td> </tr> <tr> <td width="30%"><font face="Arial" size="4"><b>Text:</b></font></td> <td width="70%"><textarea rows="4" name="MsgText" cols="20"></textarea></td> </tr> <tr> <td width="30%"> </td> <td width="70%"></td> </tr> <tr> <td width="30%"><input type="submit" value="Send" name="SendButton"></td> <td width="70%"><input type="reset" value="Reset" name="ResetButton"></td> </tr> </table> </form> </body>


</html>

Файл формата HTML использует элемент для получения значений переменных ReplyTo, SendTo HMsgText. Элемент используется также для определения формата вводимых данных. Для облегчения ввода данных, имеющихвид телефонных номеров, в файле используется таблица для ввода компонентовтелефонного номера. После того как пользователь введет данные и нажметкнопку Send, в исходном коде происходит передача данных сценарию языка PerlWebPage.pl, исходный код которого приведен ниже:

#!/usr/bin/perl

require 'DeckUtils.pl';

$mailprog = "/bin/sendmail";

# Get the CGI variables. %cgiVars = &AppUtils::ParseCGIVars();

$ReplyTo1 = $cgiVars{"ReplyTo1"}; $ReplyTo2 = $cgiVars{"ReplyTo2"}; $ReplyTo3 = $cgiVars{"ReplyTo3"}; $ReplyTo = $ReplyTo1; $ReplyTo .= "-"; $ReplyTo .= $ReplyTo2; $ReplyTo .= "-"; $ReplyTo .= $ReplyTo3; $MsgSubject = $ReplyTo;

$SendTo1 = $cgiVars{"SendTo1"}; $SendTo2 = $cgiVars{"SendTo2"}; $SendTo3 = $cgiVars{"SendTo3"}; $SendTo = $SendTo1; $SendTo .= $SendTo2; $SendTo .= $SendTo3; $SendTo .= "\@messaging.sprintpcs.com";

$MsgText = $cgiVars{"MsgText"};

open(MAIL, "|$mailprog $SendTo");

print MAIL "Reply-To: $ReplyTo\n"; print MAIL "From: Demo\@waplib.com\n"; print MAIL "To: $SendTo\n"; print MAIL "Subject: $MsgSubject\n\n";

print MAIL "$MsgText\n";

close(MAIL);

print "Content-type: text/html\n\n"; print "<HTML>\n"; print "<Body>\n"; print "Message has been sent to: $SendTo\n"; print "</Body>\n"; print "</HTML>\n";

В начале сценария используется функция $cgiVars для извлечения значений параметров. Так как в файле формата HTML данные ReplyTo и SendTo вводятсятремя частями (три части, составляющие телефонный номер), файл должен извлекать значения параметров в переменные ReplyTol, ReplyTo2, ReplyToS,SendTol, SendTo2, SendTo3.Исходный код должен объединить эти значения в переменные ReplyTo И SendTo.

Далее, сценарий создает и пересылает сообщение электронной почты. Приокончании работы сценарий также создает новый файл формата HTML, сообщающий пользователю о том, что сообщение передано.


Пересылка сообщений посредством сети Интернет

Пересылка сообщений посредством сети Интернет

Для пересылки сообщений описанные ранее "беспроводные" приложения просто пересылают данные сценарию языка Perl, который, запускаясь, посылает сообщение электронной почты в центр сообщений Sprint PCS. Поэтому имеетсмысл разработать Web-страницу, с которой можно будет посылать сообщения
другим людям.
Рисунок 9.5 отображает подобную страницу (файл WebPage.html), которая приглашает пользователя ввести информацию SendTo, ReplyTo и MsgText.
Если вы захотите протестировать файл WebPage.html, то,просматривая меню приложений сайта waplib.com, вы не найдете там приложения WebPage.html, Так сделано потому, чтофайл WebPage.html не является "беспроводным" приложением.Подобный файл необходимо запускать в стандартном браузере,таком как, например, Microsoft Internet Explorer. ФайлWebPage.html можно запустить в своем браузере из папкиChaptered, которая находится на прилагаемом к книге компакт-диске, или найти его в Интернете по адресуwww.waplib.com/WebPage/WebPage.html.

Подробнее о приложении WapPage.hdml

Подробнее о приложении WapPage.hdml

Как и приложение формата WML, файл WapPage.hdml позволяет пользователюпослать сообщение на сотовый телефон сети Sprint PCS. Дека WapPage.hdml также взаимодействует со сценарием языка Perl, содержание которой практическиидентично сценарию WapPageWML.pl. Дека WapPage.hdml имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Entry Name=Start Format=NNN-NNN-NNNN Key=ReplyTo Default="">
<Action Type=Accept Task=GO Dest=#GetTo>
<Center>WAP Page <br><br>Reply To:
</Entry>
<Entry Name=GetTo Format=NNN-NNN-NNNN Key=SendTo Default="">
<Action Type=Accept Task=GO Dest=#GetText>
<Center>WAP Page <br><br>Send To:
</Entry>
<Entry Name=GetText Format=80M Key=MsgText Default="">
<Action Type=Accept Task=GO Dest=#Confirm>
<Center>WAP Page <br><br>Message:
</Entry>
<Display Name=Confirm>
<Action Type=Accept Task=GO Label=Send Method=Post PostData=$(ReplyTo:noesc)&$(SendTo:noesc)&$ (MsgText:noesc) Dest=../waplibcgi/WapPageHDML.pl>
<Center>WAP Page <br>Reply-To: $(ReplyTo) <br>To: $(SendTo) <br>Text: $(MsgText)
</Display>
</HDML>
Первый в исходном коде элемент сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке, атть=0 сообщает ему о невозможности кэширования (таким образом, браузер должен перезагружать эту деку каждый раз при обращении к ней пользователя).
Дека использует те же имена переменных - SendTo, ReplyTo, MsgText. Для обеспечения пользователю ввода информации используется элемент , который также определяет и формат данных. После того как данные будут введены,приложение передает управление карте Confirm, которая отображает приглашение к нажатию Send (Послать). Когда пользователь нажимает Send (Послать),приложение вызывает сценарий WapPageHDML.pl, который и выполняет основную обработку полученной информации.

Подробнее о приложении WapPage.wml

Подробнее о приложении WapPage.wml

Когда пользователь запускает приложение WapPage, дека WapPage.wml отображает запросы на ввод номера пользователя для ответа, номера получателя и непосредственно текстового сообщения. После того как пользователь введет эту информацию, приложение подключает сценарий языка Perl WebPageWML.pl, который и выполняет большинство необходимых действий. Дека WapPage.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" forua="true"/>
</head>
<card id="WAPPage" title="WAP Page">
<onevent type="onenterforward">
<refresh> <setvar name="SendTo" value="" /> <setvar name="MsgText" value="" /> </refresh>
</onevent>
<onevent type="onenterbackward">
<refresh> <setvar name="SendTo" value="" /> <setvar name="MsgText" value="" /> </refresh>
</onevent>
<do type="accept"> <go href="#Confirm" /> </do>
<p align="center">
WAP Page<br/>
</p>
<p align="left">
Reply To: <input name="ReplyTo" type="text" format="NNN-NNN-NNNN" />
</p>
<p align="center">
WAP Page<br/>
</p>
<p align="left">
Send To: <input name="SendTo" type="text" format="NNN-NNN-NNNN" />
</p>
<p align="center">


WAP Page<br/>

</p>

<p align="left">

Message: <input name="MsgText" type="text" format="80M" />

</p>

</card>

<card id="Confirm">

<do type="accept" label="Send"> <go method="post" href="../waplibcgi/WapPageWML.pl"> <postfield name="ReplyTo" value="$(ReplyTo)&"/> <postfield name="SendTo" value="$(SendTo)&"/> <postfield name="MsgText" value="$(MsgText)"/> </go> </do>

<p align="center">

WAP Page

</p>

<p align="left" mode="wrap">

Reply-To: $(ReplyTo) <br/>To: $(SendTo) <br/>Text: $(MsgText)

</p>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/> </head>


Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом. -

Приложение использует три переменные для отслеживания введенной пользователем информации: ReplyTo, SendTo, MsgText. За первыми строками исходного кода деки используются два элемента для очистки значений переменных SendTo и MsgText, в случае, если пользователь будет продвигаться впередили назад в приложении, используя команды <до> и .

Событие Onenterforward происходит в том случае, когда пользователь переходит к карте с помощью команды <до>. Аналогично, когда используется команда, происходит событие Onenterbackward. После этого приложение передает сообщение сценарию языка Perl, который использует элемент <до> для возврата в начало и пользователь может послать другое сообщение, если желает. Приложение полагает, что номер в переменной ReplyTo остается прежним, поэтомуи не удаляет его каждый раз, как две другие переменные.

<onevent type="onenterforward">

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


</onevent>

<onevent type="onenterbackward">

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

</onevent>

Далее, в исходном коде используется элемент для определения формататрех вводимых переменных. Как вы видите, элементы следуют в том жепорядке, в каком они появляются на дисплее телефона. Заметьте также, что элемент определяет формат для каждой из переменных. Формат NNN-NNN-NNNN для переменных SendTo и ReplyTo, к примеру, ограничивает значение каждой переменной числовыми данными в виде телефонного номера. Аналогично,формат 80М для переменной MsgText допускает ввод не более 80 символов.

После того как пользователь введет желаемые данные, приложение обратится ккарте Confirm (Подтверждение), отображающей данные, которые необходимопередать. После того как пользователь нажмет кнопку Send (Послать), дека передаст данные сценарию языка Perl WapPageWML.pl, как показано ниже:

Карта использует элемент для отображения итогового сообщения и кнопкиSend на дисплее сотового телефона. Если пользователь нажимает Send, данныепередаются сценарию языка Perl.

Подробнее о сценарии языка Perl WapPage.pl

Подробнее о сценарии языка Perl WapPage.pl

Как было сказано выше, каждый раз, когда пользователь выбирает опцию Send,приложение WapPage.wml запускает сценарий языка Perl, который и посылает
данные конкретному получателю сообщения. Далее, этот сценарий создает новую деку формата WML, которая после обработки браузером отображает сообщение о подтверждении отправки сообщения. Как вы увидите, для отправки сообщения просто используется электронная почта (e-mail). Исходный код сценарияWapPageWML.pl приведен ниже:
#!/usr/bin/perl
require 'DeckUtils.pl';
$mailprog = "/bin/sendmail";
# Get the CGI variables. %cgiVars = &AppUtils::ParseCGIVars(); $ReplyTo = $cgiVars{"ReplyTo"}; $SendTo = $cgiVars{"SendTo"}; $SendTo =~ s/-//g; $SendTo .= "\@messaging.sprintpcs.com"; $MsgText = $cgiVars{"MsgText"};
open(MAIL, "|$mailprog $SendTo");
print MAIL "From: Demo\@WapLib.com\n"; print MAIL "To: $SendTo\n"; print MAIL "Subject: $ReplyTo\n\n";
print MAIL "$MsgText\n";
close(MAIL);
print "Content-type: text/vnd.wap.wml\n\n"; print "<?xml version=\"1.0\"?>\n"; print "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"\n"; print "\"http://www.wapforum.org/DTD/wml_1.1.xml\">\n\n"; print "<wml>\n"; print "<card>\n"; print "<do type=\"accept\">\n"; print "<go href=\"../WapPage/WapPage.wml\" />\n"; print "</do>\n"; print "<p align=\"left\">\n"; print "Message has been sent to: $SendTo\n"; print "</p>\n"; print "</card>\n"; print "</wml>\n";
Первая строка сценария представляет собой комментарий, сообщающий интерпретатору командной строки, где находится интерпретатор языка Perl.


Втораястрока информирует интерпретатор языка о том, что этот сценарий требуеттакже для работы сценарий языка Perl DeckUtils.pl.

Сценарий DeckUtils.pl поставляется совместно с SDK и содержит функцию РагseCGlVars, извлекающую пары данных имя/значение, которые передает сценарию карта Confirm. Далее, сценарий просто определяет символ для краткой записи, имеющий имя mailprog. После этого приложение анализирует список полученных параметров (которые передает ему карта Confirm формата WML) дляизвлечения переменных SendTo, ReplyTo и MsgText. После этого приложениезапускает почтовую программу и использует print для адресации собщения, ввода текста сообщения и так далее. Как было сказано, сценарий всего лишь пересылает почту на телефоны Sprint PCS. Если вы проанализируете исходный код, выувидите, что он присоединяет адрес электронной почты@messaging.sprintpcs.com к адресу SendTo:

$SendTo .= "\@messaging.sprintpcs.com";

Далее, сценарий закрывает почтовую программу, которая сама посылает сообщение получателю. После этого он создает новую деку, которая отображает дляпользователя посланное сообщение. Сценарий пересылает сообщения посредством сети Sprint PCS. Для передачи сообщения пользователю, используещему услуги другого провайдера, вы должны знать адрес для сообщений этому провайдеру и необходимый формат данных. К примеру, компания AT&T использует 10-значный номер телефона, такой же, как и Sprint. К ней вы можете обратиться поадресу @mobile.att.net.

Пoдрoбнee o WapPageHDML.pl

Пoдрoбнee o WapPageHDML.pl

Когда пользователь вводит информацию ReplyTo, SendTo и MsgText в приложении WapPageHDML.pl, оно передает данные сценарию WapPageHDML.pl, который,в свою очередь, передает сообщение электронной почты центру сообщенийSprint PCS, непосредственно доставляющему сообщение получателю. Как вы, наверное, уже поняли, элементы передачи сообщения в сценарии WapPageHDML.plпрактически идентичны элементам в сценарии, описанным в этой главе выше.Исходный код сценарий приведен ниже:
#!/usr/bin/perl
$mailprog = "/bin/sendmail";
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$ReplyTo = $data[0]; $SendTo = $data[1]; $SendTo =~ s/-//g; $SendTo .= "\@messaging.sprintpcs.com"; $MsgText = $data[2];
open(MAIL, "|$mailprog $SendTo");
print MAIL "From: Demo\@WapLib.com\n"; print MAIL "To: $SendTo\n"; print MAIL "Subject: $ReplyTo\n\n";
print MAIL "$MsgText\n";
close(MAIL);
print "Content-type: text/x-hdml\n\n"; print "<HDML Version=3.0 Markable=True TTL=0>\n\n"; print "<Display>\n"; print "<Action Type=Accept Task=GO Dest=../WapPage/WapPage.hdml"; print " Vars=SendTo=&MsgSubject=&MsgText=>"; print "Message has been sent to: $SendTo\n"; print "</Display>\n"; print "</HDML>\n";
Если вы сравните эти два сценария языка Perl, вы увидите, что каждый из ниханализирует переданные параметры по-своему. Это происходит в связи с тем, чтоpostfield из языка WML работает несколько иначе по сравнению с postdata изязыка HDML Postfield передает пары имя/значение, a postdata передает только значения данных, поэтому приложение должно знать их порядок.

Приглашение к вводу номерадля ответа

Рисунок 9.1. Приглашение к вводу номерадля ответа

Приглашение к вводу номерадля ответа

Подробнее о приложении WapMail

Подробнее о приложении WapMail.hdml

Подробнее о приложении WapMail.hdml

Как и приложение формата WML, файл WapMail.hdml позволяет пользователюпосылать сообщения электронной почты по всему миру. Файл WapMail.hdml такжесвязан со сценарием языка Perl, содержание которого практически идентичносценарию WapMail.pl. Дека WapMail.hdml имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Entry Name=Start Format=*m Key=ReplyTo Default="">
<Action Type=Accept Task=GO Dest=#GetTo>
<Center>WAP Mail <br><br>Reply To:
</Entry>
<Entry Name=GetTo Format=*m Key=SendTo Default="">
<Action Type=Accept Task=GO Dest=#GetSubject>
<Center>WAP Mail <br><br>Send To:
</Entry>
<Entry Name=GetSubject Format=*M Key=MsgSubject Default="">
<Action Type=Accept Task=GO Dest=#GetText>
<Center>WAP Mail <br><br>Subject:
</Entry>
<Entry Name=GetText Format=*M Key=MsgText Default="">
<Action Type=Accept Task=GO Dest=#Confirm>
<Center>WAP Mail <br><br>Message:
</Entry>
<Display Name=Confirm>
<Action Type=Accept Task=GO Label=Send Method=Post PostData=$(ReplyTo:noesc)&$(SendTo:noesc) &$(MsgSubject:noesc)&$(MsgText:noesc) Dest=../waplibcgi/WapMailHDML.pl>
<Center>WAP Mail <br>Reply-To: $(ReplyTo) <br>To: $(SendTo) <br>Subject: $(MsgSubject) <br>Text: $(MsgText)
</Display>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке,a TTL=0 сообщает о невозможности кэширования (таким образом, браузер должен перезагружать эту деку каждый раз при обращении к нему пользователя).
Дека использует те же имена переменных, что и дека формата WML - SendTo, ReplyTo, MsgSubject и MsgText. Для обеспечения пользователю ввода информациииспользуется элементы , которые также определяют формат вводимыхданных.
Снова форматы *м и *т позволяют вводить любые символы, числа и алфавитно-цифровые знаки, причем *М - по умолчанию считает первый символ символомверхнего регистра, *т - по умолчанию символом нижнего регистра.
После того как пользователь введет данные, приложение передает управлениекарте Confirm, которая отображает приглашение нажать кнопку Send. Если Sendнажата, приложение запускает сценарий языка Perl WapMailHDML.pl, который ивыполняет основную обработку данных.

Подробнее о приложении WapMail.wml

Подробнее о приложении WapMail.wml

Когда вы запустите приложение WapMail, дека WapMail.wml отобразит пользователю приглашение ввести адрес для ответа, электронный адрес получателя, темусообщения и сам текст сообщения. После того как пользователь введет всю этуинформацию, приложение запустит сценарий языка Perl WapMailWML.pl, которыйи перешлет это сообщение электронной почты. Дека WapMail.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" forua="true"/>
</head>
<card id="WAPMail" title="WAP Mail">
<onevent type="onenterforward">
<refresh> <setvar name="SendTo" value="" /> <setvar name="MsgSubject" value="" /> <setvar name="MsgText" value="" /> </refresh>
</onevent>
<onevent type="onenterbackward">
<refresh> <setvar name="SendTo" value="" /> <setvar name="MsgSubject" value="" /> <setvar name="MsgText" value="" /> </refresh>
</onevent>
<do type="accept"> <go href="#Confirm" /> </do>
<p align="center">
WAP Mail<br/>
</p>
<p align="left">
Reply To: <input name="ReplyTo" type="text" format="*m" />
</p>
<p align="center">
WAP Mail<br/>
</p>
<p align="left">
Send To: <input name="SendTo" type="text" format="*m" />


</p>

<p align="center">

WAP Mail<br/>

</p>

<p align="left">

Subject: <input name="MsgSubject" type="text" format="*M" />

</p>

<p align="center">

WAP Mail<br/>

</p>

<p align="left">

Message: <input name="MsgText" type="text" format="*M" />

</p>

</card>

<card id="Confirm">

<do type="accept" label="Send"> <go method="post" href="../waplibcgi/WapMailWML.pl"> <postfield name="ReplyTo" value="$(ReplyTo)&"/> <postfield name="SendTo" value="$(SendTo)&"/> <postfield name="MsgSubject" value="$(MsgSubject)&"/> <postfield name="MsgText" value="$(MsgText)"/> </go> </do>

<p align="center">

WAP Mail

</p>

<p align="left" mode="wrap">

Reply-To: $(ReplyTo) <br/>To: $(SendTo) <br/>Subject: $(MsgSubject) <br/>Text: $(MsgText)

</p>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Для отслеживания пользовательской информации приложение использует четыре переменные: ReplyTo, SendTo, MsgSubject, MsgText. За информацией заголовка деки следуют два элемента для очистки значений переменныхSendTo, MsgSubject, MsgText в случае, если пользователь будет двигаться впередили назад по приложению, используя команды <до> и . Приложение считает адрес ReplyTo неменяющимся и поэтому не производит очистку соответствующей переменной каждый раз.

Как вы уже поняли по Главе 9, событие Onenterforward происходит, когдапользователь перемещается к карте деки с помощью команды <до>.


Аналогично,когда пользователь использует команду , происходит событие

пользователь использует команду , происходит событие Onenterbackward. После того как приложение передает сообщение сценарию языка Perl, сценарийиспользует элемент <до> для возврата в начало для того, чтобы пользовательсмог, если желает, послать еще одно сообщение.

Далее, в исходном коде деки следуют элементы для определения формата четырех описанных выше переменных. Элементы внутри деки записаны в том же порядке, в котором они появляются на дисплее. Заметьте также,что элементы определяют формат для каждой из переменных. Формат*М позволяет вводить алфавитно-цифровые знаки смешанного регистра, числаили имена, начинающиеся, по умолчанию, со знака в верхнем регистре. Вообще,оба форматы *М и *т позволяют вводить имена, числа и алфавитно-цифровыезнаки, причем М - по умолчанию первый символ верхнего регистра, m - по умолчанию первый символ нижнего регистра.

После ввода пользователем всех данных, приложение передает управление картеConfirm (Подтверждение), которая отображает сообщение о данных, предназначенных для пересылки. После выбора пользователем опции Send, карта пересылает данные сценарию языка Perl WapMailWML.pl.

Подробнее о сценарии языка Perl WapMail.pl

Подробнее о сценарии языка Perl WapMail.pl

Как было сказано выше, когда пользователь выбирает опцию Send, приложениеWapMail.wml вызывает сценарий языка Perl, который и пересылает сообщениеэлектронной почты выбранному пользователю. Далее сценарий создает новуюдеку формата WML, которая запускается в браузере протокола WAP и отображаетсообщение об успешной пересылке сообщения. Как вы увидите, для пересылкисообщения сценарий просто использует программу пересылки почты ОС Unix.Исходный код сценария WapMailWML.pl приведен ниже:
#!/usr/bin/perl
require 'DeckUtils.pl';
$mailprog = "/bin/sendmail";
# Get the CGI variables. %cgiVars = &AppUtils::ParseCGIVars(); $ReplyTo = $cgiVars{"ReplyTo"}; $SendTo = $cgiVars{"SendTo"}; $MsgSubject = $cgiVars{"MsgSubject"}; $MsgText = $cgiVars{"MsgText"};
open(MAIL, "|$mailprog $SendTo");
print MAIL "Reply-To: $ReplyTo\n"; print MAIL "From: Demo\@waplib.com\n"; print MAIL "To: $SendTo\n"; print MAIL "Subject: $MsgSubject\n\n";
print MAIL "$MsgText\n";
close(MAIL);
print "Content-type: text/vnd.wap.wml\n\n"; print "<?xml version=\"1.0\"?>\n"; print "<!DOCTYPE wml PUBLIC \"- //WAPFORUM//DTD WML 1.1//EN\"\n"; print "\"http://www.wapforum.org /DTD/wml_1.1.xml\">\n\n"; print "<wml>\n"; print "<card>\n"; print "<do type=\"accept\">\n"; print "<go href=\"../WapMail/WapMail.wml\" />\n"; print "</do>\n"; print "<p align=\"left\">\n"; print "Message has been sent to:<br/>\n"; print "$SendTo\n"; print "</p>\n"; print "</card>\n"; print "</wml>\n";
Если вы внимательно проанализируете элемент open, вы увидите, что символуmailprog предшествует знак конвейера "|".


Имя mailprog является просто указателем на программу пересылки почты. Приложение использует знак конвейера"|", потому что открывает программу и передает ей данные по конвейеру посредством print

Первая строка сценария является всего лишь комментарием, сообщающим интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока сообщает этому интерпретатору, что исходный сценарий требует другойсценарий DeckUtils.pl из SDK и содержит функцию ParseCGIVars, которая извлекает пары данных имя/значение, передаваемые сценарию из карты Confirm. Далее сценарий для сокращения записи присваивает переменной mailprog строковое значение полного пути к программе

Приложение анализирует список параметров (которые передаются из картыConfirm) и присваивает извлеченные значения переменным SendTo, ReplyTo,MsgSubject и MsgText. Далее, приложение запускает почтовую программу и использует print для адресации сообщения, ввода текста сообщения и так далее.Как вы видите, приложение присваивает значение ReplyTo заодно и значениюFrom сообщения. Значение From сообщает приложению, что оно было послано отDemo@waplib.com (вы можете изменить это значение, ссылаясь на свой собственный сайт в Сети). Значение ReplyTo, в отличие от From, определяет адрес, покоторому будет передан ответ, если получатель сообщения захочет на него ответить (значение ReplyTo соответствует значению, введенному пользователем призапуске приложения).

После того как сценарий закрывает почтовую программу, она пересылает сообщение получателю. Далее, сценарий создает новую деку, сообщающую об успешной пересылке сообщения.

Подробнее о сценарии языка Perl WapMailHDML.pl

Подробнее о сценарии языка Perl WapMailHDML.pl

После того как пользователь введет все данные для посылки сообщения электронной почты внутри приложения WapMail.hdml, оно пересылает данные сценариюWapMailHDML.pl, который и осуществляет посылку сообщения. Очевидно, что элементы для пересылки сообщения в сценарии WapMailHDML.pl аналогичны использующимся в сценарии, описанном выше в этой главе. Они приведены ниже:
#!/usr/bin/perl
$mailprog = "/bin/sendmail";
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$ReplyTo = $data[0]; $SendTo = $data[1]; $MsgSubject = $data[2]; $MsgText = $data[3];
open(MAIL, "|$mailprog $SendTo");
print MAIL "Reply-To: $ReplyTo\n"; print MAIL "From: Demo\@waplib.com\n"; print MAIL "To: $SendTo\n"; print MAIL "Subject: $MsgSubject\n\n";
print MAIL "$MsgText\n";
close(MAIL);
print "Content-type: text/x-hdml\n\n"; print "<HDML Version=3.0 Markable=True TTL=0>\n\n"; print "<Display>\n"; print "<Action Type=Accept Task=GO Dest=../WapMail /WapMail.hdml"; print " Vars=SendTo=&MsgSubject=&MsgText=>"; print "Message has been sent to:<br>\n"; print "$SendTo\n"; print "</Display>\n"; print "</HDML>\n";
Если вы сравните описанные сценарии, то, как и в Главе 9, вы увидите, что онипо-разному анализируют данные передаваемых им параметров. Это происходитпотому, что элемент postf ield языка WML работает не так, как элемент postdataязыка HDML. Как было сказано в Главе 9, postf ield передает параметры парамиимя/значение. В отличие от него элемент postdata передает только значенияданных. Это означает, что приложение должно знать, в какой последовательности передаются данные. Как вы можете видеть, сценарий просто анализируетданные параметров, создает и пересылает сообщения электронной почты, и после этого создает новую деку формата HDML, которая информирует пользователяоб успешной передаче сообщения.


Приглашение к вводу адресадля ответа

Рисунок 10.1. Приглашение к вводу адресадля ответа

Приглашение к вводу адресадля ответа

Ввод адреса электронной почтиполучателя

Рисунок 10.2. Ввод адреса электронной почтиполучателя

Ввод адреса электронной почтиполучателя

Ввод текста сообщения

Рисунок 10.4. Ввод текста сообщения

Ввод текста сообщения


Для того чтобы запустить приложение WapMail из своей собственной системы, вы должны использовать операционную систему Unixили Linux. Вы можете также запустить это приложение с сайтаwaplib.com.

Подробнее о приложении FlightSchedule

Подробнее о приложении FlightSchedule.hdml

Подробнее о приложении FlightSchedule.hdml

Как и приложение формата WML, файл FlightSchedule.hdml позволяет пользователю определить состояние выбранного рейса, используя переносное устройство(в нашем случае сотовый телефон). Этот файл имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=GetAirline1 Key=AirCode>
<Action Type=Accept Task=GO Dest=#GetFlightNum>
<Center>Flight Schedule <br><Line>Airline:
<CE Value=SU>Aeroflot <CE Value=AC>Air Canada <CE Value=AF>Air France <CE Value=NZ>Air New Zealand <CE Value=AS>Alaska Airlines <CE Value=AQ>Aloha Airlines <CE Value=HP>America West <CE Value=AA>American Airlines <CE Value=TZ>American Trans Air <CE Task=GO Dest=#GetAirline2>...More
</Choice>
<Choice Name=GetAirline2 Key=AirCode>
<Action Type=Accept Task=GO Dest=#GetFlightNum> <Action Type=Soft1 Label=Back Task=GO Dest=#GetAirline1>
<Center>Flight Schedule <br><Line>Airline:
<CE Value=CO>Continental <CE Value=DL>Delta Airlines <CE Value=LH>Lufthansa <CE Value=JL>Japan Airlines <CE Value=KL>KLM Royal Dutch <CE Value=NW>Northwest Airlines <CE Value=QF>Qantas Airlines <CE Value=QQ>Reno Air <CE Value=SR>SwissAir <CE Task=GO Dest=#GetAirline3>...More
</Choice>
<Choice Name=GetAirline3 Key=AirCode>
<Action Type=Accept Task=GO Dest=#GetFlightNum> <Action Type=Soft1 Label=Back Task=GO Dest=#GetAirline2>
<Center>Flight Schedule <br><Line>Airline:
<CE Value=TW>TWA <CE Value=UA>United Airlines <CE Value=US>USAir <CE Value=VS>Virgin Atlantic


</Choice>

<Entry Name=GetFlightNum Format=5N Key=FlightNum Default="">

<Action Type=Accept Task=GO Label=Find Method=Post PostData=$(AirCode)&$(FlightNum) Dest=../waplibcgi/FlightScheduleHDML.pl>

Flight Number:

</Entry>

</HDML>

Первый элемент внутри деки сообщает браузеру (или другим программистам), какая версия языка HDML используется приложением. Далее выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке, атть=0 сообщает ему о невозможности кэширования (таким образом, браузер должен перегружать эту деку каждый раз при обращении к нему пользователя).

Как вы видите, для отображения списка авиакомпаний, приложение используетэлемент . Внутри используется элемент для определения места в деке, куда приложение передает управление, когда пользовательпроизводит выбор авиакомпании. В отличие от версии формата WML, где используются два отдельных файла (один для получения названия авиакомпании иодин для получения номера рейса), в версии приложения формата HDML используется только один файл. Если вы подробнее изучите приложение, вы заметите,что в элементе с именами GetAirline2 и GetAirlineS используетсяэлемент , который определяет место в деке, куда передается управлениепосле того как пользователь нажимает кнопку Back (Назад).

После выбора пользователем авиакомпании в исходном коде осуществляется переход к элементу GetFlightNum, который предлагает пользователю ввести номеррейса и загружает сценарий языка Perl FlightScheduleHDML.pl.

Подробнее о приложении FlightSchedule.wml

Подробнее о приложении FlightSchedule.wml

Когда пользователь запускает приложение FlightSchedule, дека FlightSchedule.wmlотображает список авиакомпаний, из которого пользователь может сделать свойвыбор. После ввода названия авиакомпании, в приложении предлагается ввестиномер рейса и затем подключается сценарий языка Perl (файл FlightSchedule.pl).Дека FlightSchedule.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" forua="true"/>
</head>
<card id="GetAirline1">
<onevent type="onenterforward">
<refresh>
<setvar name="AirCode" value="" /> <setvar name="FlightNum" value="" />
</refresh>
</onevent>
<onevent type="onenterbackward">
<refresh>
<setvar name="AirCode" value="" /> <setvar name="FlightNum" value="" />
</refresh>
</onevent>
<do type="accept"> <go href="GetFlightNum.wml" /> </do>
<p align="center">
Flight Schedule<br/>
</p>
<p align="left" mode="nowrap">
Airline:
<select name="AirCode">
<option value="SU">Aeroflot</option> <option value="AC">Air Canada</option> <option value="AF">Air France</option> <option value="NZ">Air New Zealand</option> <option value="AS">Alaska Airlines</option> <option value="AQ">Aloha Airlines</option> <option value="HP">America West</option> <option value="AA">American Airlines</option> <option value="TZ">American Trans Air</option> <option onpick="#GetAirline2">...More</option>


</select>

</p>

</card>

<card id="GetAirline2">

<onevent type="onenterforward">

<refresh>

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

</refresh>

</onevent>

<onevent type="onenterbackward">

<refresh>

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

</refresh>

</onevent>

<do type="accept"> <go href="GetFlightNum.wml" /> </do>

<do type="options" label="Back"> <go href="#GetAirline1" /> </do>

<p align="center">

Flight Schedule<br/>

</p>

<p align="left" mode="nowrap">

Airline:

<select name="AirCode">

<option value="CO">Continental</option> <option value="DL">Delta Airlines</option> <option value="LH">Lufthansa</option> <option value="JL">Japan Airlines</option> <option value="KL"& gtKLM Royal Dutch</option> <option value="NW">Northwest Airlines</option> <option value="QF">Qantas Airlines</option> <option value="QQ">Reno Air</option> <option value="SR">SwissAir</option> <option onpick="#GetAirline3">...More</option>

</select>

</p>

</card>

<card id="GetAirline3">

<onevent type="onenterforward">


<refresh>

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

</refresh>

</onevent>

<onevent type="onenterbackward">

<refresh>

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

</refresh>

</onevent>

<do type="accept"> <go href="GetFlightNum.wml" /> </do>

<do type="options" label="Back"> <go href="#GetAirline2" /> </do>

<p align="center">

Flight Schedule<br/>

</p>

<p align="left" mode="nowrap">

Airline:

<select name="AirCode">

<option value="TW">TWA</option> <option value="UA">United Airlines</option> <option value="US">USAir</option> <option value="VS">Virgin Atlantic</option>

</select>

</p>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Далее, за элементами заголовка в деке определяется первая карта, которая в нашем случае называется GetAirlinel. Основной задачей этой карты является предоставление пользователю возможности произвести выбор из списка авиакомпаний. Цифра 1 в конце имени этой карты сообщает о том, что она первая изтрех подобных карт. Приложению требуется много подобных карт для обработкивыбора пользователя из-за большого числа авиакомпаний.

Внутри каждой карты GetAirline приложение использует два элемента, которые обрабатывают выбор пользователем кнопок <до> или. В каждом из случаев код обработки этих событий просто переинициализирует переменные AirCode (Код авиакомпании) и FlightNum (Номер рейса),присваивая им значения нуля.


После этого в каждой из карт используется элемент для предоставления пользователю возможности ввода номера рейса. В этом элементе поле тахlength ограничивает количество вводимых знаков до пяти. Аналогично, формат*N позволяет пользователю вводить только числовые данные. После ввода пользователем желаемой информации о полетах, дека использует элемент дляподключения сценария FlightScheduleWML.pl, который описан ниже.

Подробнее о сценарии языка Perl FlightScheduleWML.pl

Подробнее о сценарии языка Perl FlightScheduleWML.pl

Как было сказано выше, каждый раз, когда пользователь производит выбор авиакомпании и определяет номер рейса, приложение FlightSchedule.wml запускаетсценарий языка Perl, который отображает информацию о текущем состояниирейса или выдает сообщение об ошибке, если такой рейс не существует. Сценарий FlightScheduleWML.pl имеет следующий исходный код: #!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars(); $AirCode = $cgiVars{"AirCode"}; $FlightNum = $cgiVars{"FlightNum"};
if ($AirCode eq "SU") { $AirName = "Aeroflot";
if ($FlightNum eq "1") { $ArriveCity = "Moscow"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "AC")
{ $AirName = "Air Canada";
if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "AF")
{ $AirName = "Air France";
if ($FlightNum eq "1") { $ArriveCity = "Paris"; $ArriveTime = "9:45 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "London"; $ArriveTime = "11:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "NZ")
{ $AirName = "Air New Zealand";
if ($FlightNum eq "1") { $ArriveCity = "Auckland"; $ArriveTime = "8:50 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Sydney"; $ArriveTime = "9:00 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "AS")
{ $AirName = "Alaska Airlines";


if ($ FlightNum eq "1") { $ArriveCity = "Portland"; $ArriveTime = "6:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "7:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "AQ")

{ $AirName = "Aloha Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Hilo"; $ArriveTime = "11:15 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:45 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "HP")

{ $AirName = "America West";

if ($FlightNum eq "1") { $ArriveCity = "Las Vegas"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "PHoenix"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "AA")

{ $AirName = "American Airlines";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Phoenix"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "TZ")

{ $AirName = "American Trans Air";

if ($FlightNum eq "1") { $ArriveCity = "Chicago"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "San Francisco"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "CO")

{ $AirName = "Continental";

if ($FlightNum eq "1") { $ArriveCity = "Boston"; $ArriveTime = "6:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "DL")


{ $AirName = "Delta";

if ($ FlightNum eq "1") { $ArriveCity = "Atlanta"; $ArriveTime = "7:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "8:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "LH")

{ $AirName = "Lufthansa";

if ($FlightNum eq "1") { $ArriveCity = "Berlin"; $ArriveTime = "9:30 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Chicago"; $ArriveTime = "9:00 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "JL")

{ $AirName = "Japan Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Tokyo"; $ArriveTime = "9:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "KL")

{ $AirName = "KLM Royal Dutch";

if ($FlightNum eq "1") { $ArriveCity = "London"; $ArriveTime = "10:00 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:00 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "NW")

{ $AirName = "Northwest Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Seattle"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Portland"; $ArriveTime = "7:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "QF")

{ $AirName = "Qantas Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Melbourne"; $ArriveTime = "7:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Tokyo"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }


elsif ($ AirCode eq "QQ")

{ $AirName = "Reno Air";

if ($FlightNum eq "1") { $ArriveCity = "Reno"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "SR")

{ $AirName = "Swiss Air";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "TW")

{ $AirName = "TWA";

if ($FlightNum eq "1") { $ArriveCity = "Chicago"; $ArriveTime = "10:00 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "UA")

{ $AirName = "United Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Las Vegas"; $ArriveTime = "10:00 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "11:45 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "US")

{ $AirName = "USAir";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "VS")

{ $AirName = "Virgin Atlantic";

if ($FlightNum eq "1") { $ArriveCity = "London"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }


if ($ArriveCity eq "Unknown") {

$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card>

<do type=\"accept\" label=\"Done\"> <go href=\"../FlightSchedule /FlightSchedule.wml\" /> </do>

<p align=\"left\" mode=\"wrap\">

$AirName flight $ FlightNum is not in the database. Try again.

</p>

</card>

</wml>";

print $Deck; } else {

$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card>

<do type=\"accept\" label=\"Done\"> <go href=\"../FlightSchedule /FlightSchedule.wml\" /> </do>

<p align=\"left\" mode=\"wrap\">

$AirName flight $FlightNum will arrive in $ArriveCity at $ArriveTime

</p>

</card>

</wml>";

print $Deck; }

Первая строка сценария является всего лишь комментарием, сообщающим интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока сообщает этому интерпретатору, что исходный сценарий требует другойсценарий DeckUtils.pl, который содержит функции, используемые для анализапараметров, передаваемых из деки формата WML.

Далее, код использует серию конструкций if-else для определения, в первуюочередь, введенной авиакомпании, а затем и введенного номера рейса.


Для простоты в нашем приложении код поддерживает только номер рейса 1 для всехавиалиний, в некоторых случаях и номер рейса 2. В реальном приложении сценарий должен получать номера рейсов из базы данных, которая позволит обрабатывать неограниченное число рейсов.

Если сценарий идентифицирует соответствующие авиакомпанию и номер рейса,он создает новую деку формата WML, которая отображает информацию о рейсе изатем позволяет пользователю вернуться в начало приложения:

$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card>

<do type=\"accept\" label=\"Done\"> <go href=\"../FlightSchedule /FlightSchedule.wml\" /> </do>

<p align=\"left\" mode=\"wrap\">

$AirName flight $FlightNum is not in the database. Try again.

</p>

</card>

</wml>";

print $Deck;

Если приложение не может найти номер рейса, сценарий создает деку форматаWML, которая отображает сообщение о том, что этого номера рейса нет в базеданных, и пользователю предоставляется возможность вернуться в начало приложения

Подробнее о сценарии языка Perl FlightScheduleHDML.pl

Подробнее о сценарии языка Perl FlightScheduleHDML.pl

Как было описано выше, когда пользователь производит выбор авиакомпании иопределяет номер рейса в файле FlightSchedule.hdml, приложение пересылаетданные сценарию FlightScheduleHOML.pl. Как вы понимаете, элементы в исходномкоде для отображения информации о рейсе этого сценария практически идентичны элементам сценария, описанного ранее в этой главе. Описанные нижеоператоры языка Perl создают исходный код формата HDML, который используется браузером для отображения информации о рейсе или сообщения об ошибке(если номер рейса неправильный):
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$AirCode = $data[0]; $FlightNum = $data[1];
if ($AirCode eq "SU") { $AirName = "Aeroflot";
if ($FlightNum eq "1") { $ArriveCity = "Moscow"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "AC")
{ $AirName = "Air Canada";
if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "AF")
{ $AirName = "Air France";
if ($FlightNum eq "1") { $ArriveCity = "Paris"; $ArriveTime = "9:45 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "London"; $ArriveTime = "11:45 am"; } else { $ArriveCity = "Unknown"; } }
elsif ($AirCode eq "NZ")
{ $AirName = "Air New Zealand";
if ($FlightNum eq "1") { $ArriveCity = "Auckland"; $ArriveTime = "8:50 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Sydney"; $ArriveTime = "9:00 am"; } else { $ArriveCity = "Unknown"; } }


elsif ($ AirCode eq "AS")

{ $AirName = "Alaska Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Portland"; $ArriveTime = "6:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "7:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "AQ")

{ $AirName = "Aloha Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Hilo"; $ArriveTime = "11:15 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:45 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "HP")

{ $AirName = "America West";

if ($FlightNum eq "1") { $ArriveCity = "Las Vegas"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "PHoenix"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "AA")

{ $AirName = "American Airlines";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Phoenix"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "TZ")

{ $AirName = "American Trans Air";

if ($FlightNum eq "1") { $ArriveCity = "Chicago"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "San Francisco"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "CO")

{ $AirName = "Continental";

if ($FlightNum eq "1") { $ArriveCity = "Boston"; $ArriveTime = "6:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }


elsif ($ AirCode eq "DL")

{ $AirName = "Delta";

if ($FlightNum eq "1") { $ArriveCity = "Atlanta"; $ArriveTime = "7:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "8:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "LH")

{ $AirName = "Lufthansa";

if ($FlightNum eq "1") { $ArriveCity = "Berlin"; $ArriveTime = "9:30 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Chicago"; $ArriveTime = "9:00 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "JL")

{ $AirName = "Japan Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Tokyo"; $ArriveTime = "9:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "KL")

{ $AirName = "KLM Royal Dutch";

if ($FlightNum eq "1") { $ArriveCity = "London"; $ArriveTime = "10:00 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:00 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "NW")

{ $AirName = "Northwest Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Seattle"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Portland"; $ArriveTime = "7:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "QF")

{ $AirName = "Qantas Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Melbourne"; $ArriveTime = "7:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Tokyo"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }


elsif ($ AirCode eq "QQ")

{ $AirName = "Reno Air";

if ($FlightNum eq "1") { $ArriveCity = "Reno"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Las Vegas"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "SR")

{ $AirName = "Swiss Air";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "TW")

{ $AirName = "TWA";

if ($FlightNum eq "1") { $ArriveCity = "Chicago"; $ArriveTime = "10:00 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Los Angeles"; $ArriveTime = "9:30 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "UA")

{ $AirName = "United Airlines";

if ($FlightNum eq "1") { $ArriveCity = "Las Vegas"; $ArriveTime = "10:00 am"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "11:45 pm"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "US")

{ $AirName = "USAir";

if ($FlightNum eq "1") { $ArriveCity = "New York"; $ArriveTime = "8:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "Boston"; $ArriveTime = "6:45 am"; } else { $ArriveCity = "Unknown"; } }

elsif ($AirCode eq "VS")

{ $AirName = "Virgin Atlantic";

if ($FlightNum eq "1") { $ArriveCity = "London"; $ArriveTime = "10:30 pm"; } elsif ($FlightNum eq "2") { $ArriveCity = "New York"; $ArriveTime = "9:45 am"; } else { $ArriveCity = "Unknown"; } }


if ($ArriveCity eq "Unknown") {

$Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display>

<Action Type=Accept Task=GO Label=Done Dest=../FlightSchedule/FlightSchedule.hdml Vars=AirCode=&FlightNum=>

$AirName flight $ FlightNum is not in the database. Try again.

</Display>

</HDML>";

print $Deck; } else { $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display>

<Action Type=Accept Task=GO Label=Done Dest=../FlightSchedule/FlightSchedule.hdml Vars=AirCode=&FlightNum=>

$AirName flight $FlightNum will arrive in $ArriveCity at $ArriveTime

</Display>

</HDML>";

print $Deck; }

Как вы видите, обе деки формата HDML используют элементы вывода сообщения на экран сотового телефона. Аналогично, обе деки используют элементы для того, чтобы пользователь мог вернуться в началеприложения.


Подробнее о приложении PackageTracker

Отображение текущегосостояния посылки

Рисунок 12.2. Отображение текущегосостояния посылки

Отображение текущегосостояния посылки

Подробнее о приложении PackageTracker

Подробнее о приложении PackageTracker

Когда пользователь запускает приложение PackageTracker, дека Ptracker.wml предлагает пользователю ввести номер, присвоенный посылке авиакомпанией. Послеего ввода и подтверждения правильности, дека загружает сценарий языка Perl(файл PackageWML.pl). Дека Ptracker.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" forua="true"/>
</head>
<card id="Tracker" title="Package Tracker">
<onevent type="onenterforward">
<refresh> <setvar name="ABNum" value="" /> </refresh>
</onevent>
<onevent type="onenterbackward">
<refresh> <setvar name="ABNum" value="" /> </refresh>
</onevent>
<p align="center">
Package<br/> Tracker<br/>
</p>
<p align="left">
AirBill Number: <input name="ABNum" maxlength="7" title="Air Bill Number" type="text" format="AANNNNN" />
</p>
<p align="left">
Package ID#:<br/> $(ABNum)<br/>
<select> <option onpick="../waplibcgi/PackageWML.pl? $(ABNum)">Track</option> <option onpick="#Tracker">Clear</option> </select>
</p>
</card>
</wml>
Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение.


Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Далее за элементами заголовка в деке определяется единственная карта, котораяв нашем случае называется Tracker.Основной задачей этой карты является предоставление пользователю возможности ввода номера посылки. Внутри картыиспользуются два элемента , которые обрабатывают нажатие пользователем кнопок <до> и . Исходный код обработки события каждый разпросто переинициализирует переменную ABNum (номер посылки), присваивая ейзначение ноль. Далее в карте используется элемент для ввода номерапосылки. Заметьте, что в определяется формат AANNNNN, который позволяет пользователю ввести перед пятью цифрами два алфавитно-цифровых символа.

После ввода номера посылки приложение вызывает сценарий языка PerlPackageWML.pl.

Подробнее о приложении Ptracker.hdml

Подробнее о приложении Ptracker.hdml

Как и приложение формата WML, файл Ptracker.hdml позволяет увидеть текущеесостояние выбранной им посылки на дисплее своего переносного устройства(в нашем случае сотового телефона). Этот файл имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Entry Name=Tracker Format=AANNNNN Key=ABNum Default="">
<Action Type=Accept Task=GO Dest=#Confirm>
<Center>Package<BR> <Center>Tracker<BR><BR> AirBill Number:
</Entry>
<Choice Name=Confirm Key=ABNum Method=Alpha>
Package ID#: $(ABNum)
<CE Label=Track Task=GO Method=Post PostData=$(ABNum) Dest=../waplibcgi/PackageHDML.pl>Track
<CE Task=GO Dest=#Tracker Label=Clear Value="">Clear
</Choice>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам), какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает браузеру, что он может установить закладку в исходной деке, аTTL=0 сообщает браузеру о невозможности кэширования (таким образом, ему необходимо перегружать эту деку каждый раз при обращении к нему пользователя).
Как вы видите, приложение использует элемент для приглашения пользователя к вводу номера посылки. Снова используется формат AANNNNN для вводаперед пятью числами двух алфавитно-цифровых символов. Как и в предыдущемслучае, приложение запоминает значение номера посылки в переменной ABNum.
После ввода и подтверждения номера посылки, приложение вызывает сценарийязыка Perl PackageHDML.pl.

Подробнее о сценарии языка Perl PackageHDML.pl

Подробнее о сценарии языка Perl PackageHDML.pl

Как было сказано выше, после ввода пользователем номера посылки в файлеPtracker.hdml, приложение передает данные сценарию языка Perl PackageHDML.pl.Очевидно, что для отображения информации о статусе посылки в этом сценариииспользуются практически идентичные элементы, что и в описанном выше вэтой главе сценарии. Если пользователь вводит номер посылки AD12345, сценарий загружает файл AD12345.hdml, который имеет следующий исходный код:
<HDML Version=3.0 TTL=0>
<Display>
<ACTION Type=Accept Task=GO Dest=../PackageTracker/PTracker.hdml Vars=ABNum=>
<Center>Package<BR> <Center>Tracker<BR>
<Line>Package AD12345<BR> <Line>Pickup LAS 11/13/99 12:30 <Line>Left LAS 11/13/99 15:00 <Line>Arrive HOU 11/13/99 21:00 <Line>Delivered 11/14/99 09:00
</Display>
</HDML>
В исходном коде просто используются элементы для отображения информации о посылке. После просмотра пользователем выведенной информации,элемент в коде позволяет пользователю вернуться в начало приложения PackageTracker.
Как и в предыдущем случае, если пользователем введен неправильный номер посылки, сценарий языка Perl загружает файл BadlD.hdml, исходный код которогоприведен ниже:
<HDML Version=3.0 TTL=0>
<Display>
<ACTION Type=Accept Task=GO Dest=../PackageTracker/PTracker.hdml Vars=ABNum=>
<Center>Package<BR> <Center>Tracker<BR>
<BR>Unknown Package ID. Try again. <BR><BR>For this demo the only valid Package ID is AD12345
</Display>
</HDML>


Подробнее о сценарии языка Perl PackageWML.pl

Подробнее о сценарии языка Perl PackageWML.pl

Как было сказано, каждый раз после ввода пользователем номера посылки, декаPtracker.wml загружает сценарий языка Perl, который и отображает информациюо текущем статусе посылки или отображает сообщение о том, что такой посылкине существует (ошибка). Исходный код сценария PackageWML.pl приведен ниже:
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";
$Buffer = $ENV{'QUERY_STRING'};
if ($Buffer eq "AD12345") { $FileName = "../PackageTracker/AD12345.wml"; } else { $FileName = "../PackageTracker/BadID.wml"; }
open (PackageInfo, $FileName);
while (<PackageInfo>) { print; }
close (PackageInfo);
Первая строка сценария является всего лишь комментарием, сообщающим интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока сообщает браузеру протокола WAP о том, что после окончания работысценария на выходе будет создан исходный код формата WML. Далее, в исходномкоде используется функция $ENV для определения номера посылки, который декаформата WML передает сценарию как параметр.
После этого в коде используется последовательность операторов if-else дляопределения введенного пользователем номера (номер может быть толькоAD12345, единственный распознаваемый нашим приложением). Если пользователем введен именно этот номер посылки, то загружается дека AD12345.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" forua="true"/>
</head>
<card>
<do type="accept"> <go href="../PackageTracker/PTracker.wml"/> </do>
<p align="center">
Package<br/> Tracker<br/> </p>


<p align="left" mode="nowrap">

Package AD12345<br/> Pickup LAS 11/13/99 12:30<br/> Left LAS 11/13/99 15:00<br/> Arrive HOU 11/13/99 21:00<br/> Delivered 11/14/99 09:00<br/>

</p>

</card>

</wml>

В коде просто используются элементы <р> для отображения информации о посылке. В реальном приложении, в исходном его коде должен осуществляться поиск информации о посылке в базе данных, и дека, подобная описанной, создаваться в процессе работы сценария.

Если пользователь вводит неправильный номер посылки, приложение загружаетдеку BadlD.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" forua="true"/>

</head>

<card>

<do type="accept"> <go href="../PackageTracker/PTracker.wml"/> </do>

<p align="center">

Package<br/> Tracker<br/>

<br/>Unknown Package ID. Try again. <br/><br/>For this demo the only valid Package ID is AD12345

</p>

</card>

</wml>

Снова исходный код деки использует тег абзаца <р> для вывода сообщения обошибке.

Подробнее о приложении MortgageCalculator

Отображение суммы выплатыпо закладной

Рисунок 13.2. Отображение суммы выплатыпо закладной

Отображение суммы выплатыпо закладной

Подробнее о приложении MortgageCalc.hdml

Подробнее о приложении MortgageCalc.hdml

Как и приложение формата WML, файл MortgageCalc.hdml позволяет пользователю вычислить сумму выплаты по закладной, используя собственный сотовый телефон. Этот файл имеет следующий исходный код:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Mortgage Method=Alpha>
<Action Type=Accept Label=Edit> <Action Type=Soft1 Label=Calc Task=GO Dest=#CalcPayments>
<Center>Mortgage Calculator<br>
<CE Task=GOSub Dest=#GetPrincipal Vars=Principal=$Principal Receive=Principal> Principal: &dol;$Principal
<CE Task=GOSub Dest=#GetInterest Vars=Interest=$Interest Receive=Interest> Interest(%): $Interest
<CE Task=GOSub Dest=#GetYears Vars=Years=$Years Receive=Years> Years: $Years
</Choice>
<Entry Name=GetPrincipal Default=$Principal Key=Principal Format=NNNNNN*N>
<Action Type=Accept Task=Return Retvals=$Principal> Principal:&dol;
</Entry>
<Entry Name=GetInterest Default=$Interest Key=Interest Format=NN.NN>
<Action Type=Accept Task=Return Retvals=$Interest> Interest(%):
</Entry>
<Entry Name=GetYears Default=$Years Key=Years Format=NN>
<Action Type=Accept Task=Return Retvals=$Years> Years:
</Entry>
<NoDisplay Name=CalcPayments>
<Action Type=Accept Task=GO Method=Post PostData=$Principal&$Interest&$Years Dest=../waplibcgi/MortgageCalcHDML.pl>
</NoDisplay>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает, что браузер может установить закладку в исходной деке, аTTL=0 сообщает о невозможности кэширования (таким образом, браузер долженперезагружать эту деку каждый раз при обращении к ней пользователя).
Для предоставления пользователю возможности редактировать выбранное имполе (основная сумма, ссудный процент, количество лет) приложение используетэлемент . В используются элементы <СЕ> для направления
приложения к определенному месту в исходном коде, в зависимости от выборапользователя.
Дека формата HDML использует также три отдельных элемента для предоставления пользователю возможности ввода основной суммы, ссудного процента и количества лет. Внутри каждого из этих элементов поле format определяет формат вводимых в приложение данных.
После того как пользователь введет и подтвердит всю необходимую информацию, приложение переходит к карте CalcPayments, откуда и вызывается сценарий языка Perl MortgageCalcHDML.pl.

Подробнее о приложении MortgageCalculator

Подробнее о приложении MortgageCalculator

Когда пользователь запускает приложение MortgageCalculator, декаMortgageCalc.wml предлагает пользователю ввести значение основной суммы,ссудный процент и количество лет на выплату ссуды. Далее, приложение запускает сценарий языка Perl (файл MortgageCalcWML.pl). Дека MortgageCalc.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" forua="true"/>
</head>
<card id="MortgageCalc">
<do type="accept" label="Edit"> <noop /> </do>
<do type="options" label="Calc"> <go href="#CalcPayments" /> </do>
<p align="center">
Mortgage Calculator<br/>
</p>
<p align="left" mode="nowrap">
<select>
<option onpick="#GetPrincipal">Principal: $$$(Principal)</option> <option onpick="#GetInterest">Interest(%): $(Interest)</option> <option onpick="#GetYears">Years: $(Years)</option>
</select>
</p>
</card>
<card id="GetPrincipal">
<do type="accept"> <go href="#MortgageCalc" /> </do>
<p align="left">
Principal: $$ <input name="Principal" maxlength="7" format="NNNNNN*N" />
</p>
</card>
<card id="GetInterest">
<do type="accept"> <go href="#MortgageCalc" /> </do>


<p align="left">

Interest(%): <input name="Interest" maxlength="5" format="NN.NN" />

</p>

</card>

<card id="GetYears">

<do type="accept"> <go href="#MortgageCalc" /> </do>

<p align="left">

Years: <input name="Years" maxlength="2" format="NN" />

</p>

</card>

<card id="CalcPayments">

<onevent type="onenterforward">

<go method="post" href="../waplibcgi/MortgageCalcWML.pl"> <postfield name="Principal" value="$(Principal)&"/> <postfield name="Interest" value="$(Interest)&"/> <postfield name="Years" value="$(Years)"/> </go>

</onevent>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Приложение использует индивидуальные карты в деке для основной суммы,ссудного процента и количества лет. Внутри основной карты деки находитсяэлемент Д|9Л? f011!3* определяет формат данных, принимаемых приложением.

После ввода и подтверждения пользователем необходимых значений, приложение вызывает карту CalcPayment, из которой запускается сценарий языка PerlMortgageCalcWML.pl.

Подробнее о сценарии языка Perl MortgageCalcHDML.pl

Подробнее о сценарии языка Perl MortgageCalcHDML.pl

Как было сказано выше, после того как пользователь вводит всю необходимуюдля вычислений информацию в файле MortgageCalc.hdml, приложение пересылает данные сценарию MortgageCalcHDML.pl. Очевидно, что используемые для отображения информации по выплатам элементы аналогичны элементам сценария,описанного в этой главе выше. Исключение составляют только два момента: каксценарий определяет необходимые ему параметры и как он создает новую декуформата HDML для отображения результата работы приложения. Исходный кодсценария MortgageCalcHDML.pl приведен ниже:
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$Principal = $data[0]; $Interest = $data[1]; $Years = $data[2];
$MonthInt = ($Interest / 12) / 100; $Months = $Years * 12;
$Payment = $Principal * ($MonthInt / (1 - (1 + $MonthInt) ** (-$Months))); $Payment = $Payment * 100; $Payment = (int $Payment) / 100;
$Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Result1>
<Action Type=Accept Label=Done Task=GO Dest=../MortgageCalc/MortgageCalc.hdml>
<Line>Principal: &dol;$Principal<br> Interest(%): $Interest<br> Years: $Years<br> Payment: &dol;$Payment
</Display>
</HDML>";
print $Deck;


Подробнее о сценарии языка Perl MortgageCalcWML.pl

Подробнее о сценарии языка Perl MortgageCalcWML.pl

Как было сказано выше, каждый раз после ввода пользователем всей необходимой по закладной информации, карта CalcPayment активизирует сценарий языкаPerl, который вычисляет и отображает информацию по выплате. Этот сценарийMortgageCalcWML.pl имеет следующий исходный код:
#!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars();
$Principal = $cgiVars{"Principal"}; $Interest = $cgiVars{"Interest"}; $Years = $cgiVars{"Years"};
$MonthInt = ($Interest / 12) / 100; $Months = $Years * 12;
$Payment = $Principal * ($MonthInt / (1 - (1 + $MonthInt) ** (-$Months))); $Payment = $Payment * 100; $Payment = (int $Payment) / 100;
$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>
</head>
<card id=\"Result1\">
<do type=\"accept\" label=\"Done\"> <go href=\"../MortgageCalc /MortgageCalc.wml\" /> </do>
<p align=\"left\" mode=\"nowrap\">
Principal: \$\$$Principal<br/> Interest(%): $Interest<br/> Years: $Years<br/> Payment: \$\$$Payment
</p>
</card>
</wml>";
print $Deck;
Первая строка сценария представляет собой комментарий, сообщающий интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока информирует интерпретатор языка о том, что этот сценарий требуеттакже сценария языка Perl DeckUtils.pl, который содержит функции, необходимыесценарию для анализа параметров, передаваемых ему из основной деки форматаWML. После того как сценарий извлечет переданные параметры, он преобразовывает количество лет в количество месяцев и вычисляет необходимую выплату.Для избежания ошибок округления, сценарий умножает и затем делит результатна 100.

Приглашение к вводуинформации по закладной

Рисунок 13.1. Приглашение к вводуинформации по закладной

Приглашение к вводуинформации по закладной

Подробнее о приложении Weatherlnfo

Отображение информациио погоде в регионе

Рисунок 14.2. Отображение информациио погоде в регионе

Отображение информациио погоде в регионе

Подробнее о приложении Weather.hdml

Подробнее о приложении Weather.hdml

Как и файл формата WML, файл Weather.hdml позволяет пользователю получитьинтересующую его информацию о погоде, используя свой сотовый телефон. Исходный код файла Weather.hdml приведен ниже:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Main Method=Alpha>
<Center>Weather Info<BR> Search by:
<CE Task=GO Dest=#GetZipCode>Zip Code <CE Task=GO Dest=#GetCity>City <CE Task=GO Dest=#GetState>State <CE Task=GO Dest=../Weather/Wxhelp.hdml>Help
</Choice>
<Entry Name=GetZipCode Format=NNNNN Key=ZipCode Default="">
<Action Type=Prev Task=GO Dest=#Main Vars=ZipCode=>
<Action Type=Accept Task=GO Method=Post PostData=$(ZipCode) Dest=../waplibcgi/ZipWeatherHDML.pl>
<Center>Weather Info<BR><BR> Enter Zip Code:
</Entry>
<Entry Name=GetCity Format=*M Key=CityName Default="">
<Action Type=Prev Task=GO Dest=#Main Vars=CityName=>
<Action Type=Accept Task=GO Method=Post PostData=$(CityName:noesc) Dest=../waplibcgi/CityWeatherHDML.pl>
<Center>Weather Info<BR><BR> Enter City:
</Entry>
<Entry Name=GetState Format=AA Key=StateName Default="">
<Action Type=Prev Task=GO Dest=#Main Vars=StateName=>
<Action Type=Accept Task=GO Method=Post PostData=$(StateName) Dest=../waplibcgi/StateWeatherHDML.pl>
<Center>Weather Info<BR><BR> Enter State:
</Entry>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам)какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает, что браузер может установить закладку в исходной деке, аTTL=0 сообщает ему о невозможности кэширования (таким образом, браузердолжен перегружать эту деку каждый раз при обращении к ней пользователя).


Для предоставления пользователю возможности выбора почтового индекса, города, штата или режима помощи используется элемент . Внутри используются элементы <СЕ> для направления приложения в опереде-ленное место в исходном коде внутри деки. Если же выбрана опция помощи, требуется, чтобы браузер загрузил другую деку.

В деке формата HDML используются элементы для обеспечения вводапользователем почтового индекса, города или штата. Внутри каждого из этих элементов в поле format определяется формат вводимых пользователем данных.

После того как произведен выбор, приложение запускает один из сценариевязыка Perl (в зависимости от того, что выбрано: индекс, штат или город). Еслипользователем выбрана опция помощи, браузер загружает деку Wxhelp.hdml, которая имеет следующий исходный код:

<HDML Version=3.0 Markable=True TTL=0>

<Display>

<ACTION Type=Accept Task=GO Dest=../Weather/Weather.hdml>

For this demo<BR>

Zip Codes are:<BR> 87101, 87701, 89101, 89501<BR>

Cities are:<BR> Albuquerque, NM<BR> Las Vegas, NM<BR> Las Vegas, NV<BR> Reno, NV<BR>

States are:<BR> Nevada<BR> New Mexico<BR>

</Display>

</HDML>

Эта дека использует элемент для отображения доступных почтовыхиндексов, городов и штатов. После того как пользователь просмотрит интересующую его информацию и нажмет кнопку Accept (Принято), элемент даст указание браузеру перезагрузить основную деку приложения.

Подробнее о приложении Weatherlnfo

Подробнее о приложении Weatherlnfo

Когда пользователь запускает приложение Wheatherlnfo, дека Wheather.wml предлагает пользователю ввести почтовый индекс, город, штат или выбрать опциюпомощи. Основываясь на выборе пользователя, приложение осуществляет переход к локальной карте, которая находится в пределах текущего файла или деки.Дека Wheather.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" forua="true"/>
</head>
<card id="Weather" title="Weather Info">
<onevent type="onenterforward">
<refresh> <setvar name="ZipCode" value="" /> <setvar name="CiryName" value="" /> <setvar name="StateName" value="" /> </refresh>
</onevent>
<onevent type="onenterbackward">
<refresh> <setvar name="ZipCode" value="" /> <setvar name="CityName" value="" /> <setvar name="StateName" value="" /> </refresh>
</onevent>
<p align="center">
Weather Info<br/> Search by:
</p>
<p align="left">
<select title="Main">
<option onpick="#GetZipCode">Zip Code</option> <option onpick="#GetCity">City</option> <option onpick="#GetState">State</option> <option onpick="../Weather/Wxhelp.wml">Help</option>
</select>
</p>


</card>

<card id="GetZipCode">

<do type="accept"> <go href="../waplibcgi/ZipWeatherWML.pl ?$(ZipCode)" /> </do>

<p align="center">

Weather Info<br/>

</p>

<p align="left">

Enter Zip Code:

<input name="ZipCode" maxlength="6" type="text" format="NNNNN" />

</p>

</card>

<card id="GetCity">

<do type="accept"> <go href="../waplibcgi/CityWeatherWML.pl ?$(CityName)" /> </do>

<p align="center">

Weather Info<br/>

</p>

<p align="left">

Enter City:

<input name="CityName" type="text" format="*M" />

</p>

</card>

<card id="GetState">

<do type="accept"> <go href="../waplibcgi/StateWeatherWML.pl ?$(StateName)" /> </do>

<p align="center">

Weather Info<br/>

</p>

<p align="left">

Enter State:

<input name="StateName" type="text" format="AA" />

</p>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение.В нашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,

когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.

Приложение использует три переменные для хранения введенных пользователем данных: ZipCode, CityName и StateName. При запуске приложения карта использует элемент для очистки текущих значений каждой из переменных при нажатии пользователем кнопки Next (Далее) или кнопки Previous (Предыдущий) на телефоне. После этого карта использует элемент символы фунта (#), предшествующие первым тремопциям, сообщают вам, что карта, например, #GetZipCode, находится внутри текущей деки формата WML. В отличие от этого, карта для опции помощи Help находится в отдельной деке.

Внутри каждой из карт приложение использует элемент для предоставления пользователю возможности ввода необходимых данных, таких, как Название города или почтовый индекс. Если вы обратите внимание на элемент, то увидите, что поле format определяет формат соответствующих данных. К примеру, внутри карты GetZipCode использует формат NNNNN дляпредоставления возможности ввода только 5 числовых символов.

Как было сказано, если пользователь выбирает опцию Help, приложение загружает карту из деки на диске, которая в нашем случае находится в файлеWxhelp.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" forua="true"/>

</head>

<card>

<do type="accept"> <go href="../Weather/Weather.wml" /> </do>

<p align="left" mode="wrap">

For this demo<br/>

Zip Codes are:<br/> 87101, 87701, 89101, 89501<br/>

Cities are:<br/> Albuquerque, NM<br/> Las Vegas, NM<br/> Las Vegas, NV<br/> Reno, NV<br/>

States are:<br/> Nevada<br/> New Mexico<br/>

</p>

</card>

</wml>

В карте используется тег абзаца <р> для отображения списка доступных почтовых индексов, городов и штатов в нашей демо-версии приложения. Если пользователь производит нажатие на кнопку Accept (Принять), приложение используетэлемент для загрузки основной деки Weather.wml. При вводе пользователемгорода, штата или почтового индекса, приложение вызывает соответствующийсценарий языка Perl.

Подробнее о сценариях языка Perl,используемых в приложении

Подробнее о сценариях языка Perl,используемых в приложении

Когда пользователь выбирает опцию Zip Code (Почтовый индекс) в приложенииWeatherlnfo, в исходном коде ему предлагается ввести почтовый индекс. Далее запускается сценарий языка Perl, который этот индекс анализирует. Если пользователем введен разрешенный индекс (в нашем случае один из нескольких известных приложению), сценарий открывает, а затем печатает соответствующий файло погоде (вывод которого перехватывается браузером). Если пользователь ввелнедоступный почтовый индекс, сценарий открывает файл Unknown.wml, исходный код которого производит отображение сообщения об ошибке. Исходныйкод сценария языка Perl ZipWeatherWML.pl приведен ниже:
#!/usr/bin/perl
print "Content-type: text/vnd.wap.wml\n\n";
$Buffer = $ENV{'QUERY_STRING'};
if ($Buffer eq "87101") { $FileName = "../Weather/87101.wml"; } elsif ($Buffer eq "87701") { $FileName = "../Weather/87701.wml"; } elsif ($Buffer eq "89101") { $FileName = "../Weather/89101.wml"; } elsif ($Buffer eq "89501") { $FileName = "../Weather/89501.wml"; } else { $FileName = "../Weather/Unknown.wml"; }
open (WeatherInfo, $FileName);
while (<WeatherInfo>) { print; }
close (WeatherInfo);
Первая строка сценария представляет собой комментарий, сообщающий интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока информирует браузер (который перехватывает вывод) о том, что результатом работы сценария будет создание исходного кода формата WML. Далее используется функция $ENV для извлечения параметра почтового индекса.
После получения сценарием этого индекса используется серия конструкций if-else для определения, является ли введенный индекс доступным. Если сценарийраспознал введенный индекс, он присваивает имя файла формата WML этого индекса переменной $FileName. Позднее сценарий откроет и выведет соответствующий файл (который может быть и файлом Unknown.wml).

Подробнее о сценариях языка Perl,используемых в приложении

Как и приложение формата WML, приложение в формате HDML использует трисценария языка Perl для обработки выбранных пользователем почтового индекса,города или штата. Исходный код каждого из этих сценариев практически идентичен описанным ранее сценариям, поэтому здесь приведены только файлыформата HDML, которые сценарии загружают и отображают.
Когда пользователь определил почтовый индекс, приложение подключает сценарий ZipWeatherHDML.pl. Основываясь на выборе пользователя, сценарий загрузит одну из дек, например, 89101.hdml, исходный код которой приведен ниже:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Menu Method=Number>
<Action Type=Accept Label=Wx>
<Action Type=Soft1 Task=GO Dest=../Weather/Weather.hdml Label=Menu Vars=StateName=&CityName=&ZipCode=>
<Center>Las Vegas, NV<BR>
<CE Task=GO Dest=#Current>Current Conditions <CE Task=GO Dest=#Today>Today <CE Task=GO Dest=#Tomorrow>Tomorrow
</Choice>
<Display Name=Current>
<Action Type=Accept Task=GO Dest=#Menu>
<Center>Las Vegas, NV<BR>
<Line>8:50 pm PST <Line>Nov 25, 1999 <Line>Temp: 47 F <Line>Press: 30.15 <Line>Humid: 25% <Line>Wind: W at 10 mph <Line>Sky: Clear
</Display>
<Display Name=Today>
<Action Type=Accept Task=GO Dest=#Menu>
<Center>Las Vegas, NV<BR> <Line>Nov 25, 1999 <Line>Hi/Low: 70/40 F <Wrap>Mostly sunny. Light winds. Increasing clouds at night.
</Display>
<Display Name=Tomorrow>
<Action Type=Accept Task=GO Dest=#Menu>
<Center>Las Vegas, NV<BR> <Line>Nov 26, 1999 <Line>Hi/Low: 65/40 F <Wrap>Partly cloudy.


Браузер, поддерживающий протокол WAP, в свою очередь, перехватывает вывод, трактуя его каккарту формата WML. ^ v i, t ;я;

В файле формата WML для определенного индекса исходный код предлагаетпользователю выбрать, что он желает узнать: текущую погоду, погоду на сегодняшний день или прогноз на завтра. После этого, основываясь на выборе пользователя, отображается информация о погоде.

В нашем случае карта содержит всю информацию о погоде. В реальном приложении вам необходимо будет использовать базу данных для хранения информации о погоде, исходя из содержимого которой будут создаваться в процессе работы приложения соответствующие карты, содержащие необходимую информацию.

Сценарий языка Perl CityWeatherWML.pl анализирует название города, получаемоеим из приложения как параметр, и затем, основываясь на введенном названии,открывает и выводит файл, предлагающий пользователю выбрать информацию отекущей погоде, погоде на сегодняшний день или прогноз на завтра. После этогофайл выводит на дисплей телефона соответствующую погодную информацию.Сценарий CityWeatherWML.pl имеет следующий исходный код:

#!/usr/bin/perl

print "Content-type: text/vnd.wap.wml\n\n";

$Buffer = $ENV{'QUERY_STRING'}; $Buffer =~ s/%20/ /g;

if ($Buffer eq "Las Vegas") { $FileName = "../Weather/LasVegas.wml"; } elsif ($Buffer eq "Reno") { $FileName = "../Weather/89501.wml"; } elsif ($Buffer eq "Albuquerque") { $FileName = "../Weather/87101.wml"; } else { $FileName = "../Weather/Unknown.wml"; }

open (WeatherInfo, $FileName);

while (<WeatherInfo>) { print; }

close (WeatherInfo);

Как вы видите, в сценарии используется последовательность конструкций if-else для определения введенного пользователем названия города. Если сценарийобнаруживает поддерживаемое название города, он присваивает его переменной$FileName, которую использует позднее для открытия и вывода содержимогофайла. Если введенное название не поддерживается сценарием, то этой переменной присваивается имя файла Unknown.wml с целью вывода на дисплей пользователя сообщения об ошибке.


Наше приложение поддерживает всего два города: Лас-Вегас, штат Невада (Las Vegas, Nevada) и Лас-Вегас, штат Нью-Мехико (LasVegas, New Mexico). Поскольку названия городов одинаковы, приложение должно предложить пользователю выбрать один из городов. Файл LasVegas.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" forua="true"/>

</head>

<card>

<do type="prev"> <go href="../Weather/Weather.wml#GetCity" /> </do>

<p align="center" mode="wrap">

Pick City<br/>

<select>

<option onpick="../Weather/87701.wml" >Las Vegas, NM</option> <option onpick="../Weather/89101.wml" >Las Vegas, NV</option>

</select>

</p>

</card>

</wml>

Для определения выбранного пользователем города в деке используется элемент. После того как пользователь произведет выбор, загружается соответствующая городу дека формата WML (на самом деле дека, соответствующая почтовому индексу города).

Как вы понимаете, сценарий языка Perl StateWeatherWML.pl работаетаналогичным образом, используя переданный параметр для определениявыбранного пользователем штата. После этого происходит вывод необходимойинформации на дисплей сотового телефона.


</Display>

</HDML>

Дека использует элемент для определения, что желает увидеть пользователь: текущую погоду, прогноз на сегодня, прогноз на завтра. Далее, принимая вовнимание решение пользователя, управление передается одному из элементов для отображения выбранной информации. В деке используется несколько элементов для предоставления пользователю возможности вернуться назад в предыдущее меню или повторно запустить приложение в целом.

Когда пользователь определяет город (помните, что наше приложение поддерживает только четыре города), приложение подключает сценарийCityWeatherHDML.pl. Если пользователь выбирает город Las Vegas, приложениезагрузит деку LasVegas.hdml, которая имеет следующий исходный код:

<HDML Version=3.0 Markable=True TTL=0>

<Choice Method=Number>

<Action Type=Soft1 Task=GO Dest=../Weather/Weather.hdml#GetCity Label=Back Vars=CityName=>

<Center>Pick City<BR>

<CE Task=GO Dest=../Weather /87701.hdml>Las Vegas, NM <CE Task=GO Dest=../Weather /89101.hdml>Las Vegas, NV

</Choice>

</HDML>

Приложение использует элемент для предоставления пользователю возможности выбрать, погоду в каком из городов с названием Las Vegas он желает узнать. После выбора пользователем города, приложение загружает соответствующую деку формата HDML. которая и отображает информацию о погоде. В самомначале деки используется элемент для предоставления пользователювозможности вернуться к карте #GetCity, находящейся внутри основной деки.

Наконец, если пользователь выбрал штат, приложение подключает сценарийStateWeatherHDML.pl, который использует последовательность конструкций if-else для определения запрашиваемого пользователем штата. После этого приложение загружает деку, предлагающую выбрать тип прогноза. Далее происходитотображение на дисплее сотового телефона выбранной информации.

Приглашение к вводу почтовогоиндекса, города или штата

Рисунок 14.1. Приглашение к вводу почтовогоиндекса, города или штата

Приглашение к вводу почтовогоиндекса, города или штата

Подробнее о приложении CatalogOrder

Подробнее о приложении Catalogltem.hdml

Подробнее о приложении Catalogltem.hdml

Как и приложение формата WML, файл Catalogltem.hdml позволяет пользователюввести со своего сотового телефона номер и описание выбранного им товара.Файл Catalogltem.hdml имеет исходный код, приведенный ниже:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=OrderItem Method=Alpha>
<Action Type=Accept Label=Edit> <Action Type=Soft1 Label=Next Task=GO Dest=CatalogShip.hdml>
<Center>Catalog Order <Line>Item information
<CE Task=GOSub Dest=#GetItemNum Vars=ItemNum=$ItemNum Receive=ItemNum> Item #:[$ItemNum]
<CE Task=GOSub Dest=#GetItemDesc Vars=ItemDesc=$ItemDesc Receive=ItemDesc> Item:[$ItemDesc]
</Choice>
<Entry Name=GetItemNum Default=$ItemNum Key=ItemNum Format=N4N>
<Action Type=Accept Task=Return Retvals=$ItemNum> Item #:
</Entry>
<Entry Name=GetItemDesc Default=$ItemDesc Key=ItemDesc Format=M14M>
<Action Type=Accept Task=Return Retvals=$ItemDesc> Item:
</Entry>
</HDML>
Первый элемент внутри деки сообщает браузеру (или другим программистам),какая версия языка HDML используется приложением. Далее, выражение Markable=True сообщает, что браузер может установить закладку в исходной деке, аTTL=O сообщает ему о невозможности кэширования (таким образом, браузердолжен перезагружать эту деку каждый раз при обращении к нему пользователя).Далее приложение использует элементы для управления кнопками Edit(Редактировать) и Next (Следующий).
Сначала карта использует элемент для предоставления пользователювыбора того, что он желает редактировать: номер товара или его описание. Далее, основываясь на выборе пользователя, приложение передает управлениеэлементу GetltemNum или GetltemDesc для обеспечения ввода данных. Здесь используется поле format для определения формата вводимых пользователем значений переменных.


К примеру, в элементе GetltemNum определяется формат N4N.Этот формат предусматривает ввод от одного до пяти числовых символов номератовара (N4N означает, что один числовой символ обязателен, остальные четыре -по необходимости)

После ввода пользователем номера и описания товара, приложение загружаетдеку CatalogShip.hdml, которая имеет следующий исходный код:

Shipping information

Ship to:[$ShipName]

Address:[$ShipAddr1]

Address:[$ShipAddr2]

City:[$ShipCity]

State:[$ShipState]

Zip Code:[$ShipZip]

Phone:[$ShipPhone]

Ship to:

Address:

Address:

City:

State:

Zip Code:

Phone:

Для предоставления пользователю возможности выбора желаемого адресногополя приложение использует элемент . Основываясь на выборе пользовaтеля, приложение передает управление именованному элементу внутри деки, который предлагает ввести данные в определенном формате. Послеввода пользователем адреса отправки, приложение загружает декуCatalogBill.hdml, в которой предлагается ввести адрес для выписывания счета.Как вы понимаете, содержимое этой деки практически идентично содермимомуподобной деки, описанной ранее в этой главе.

После ввода информации по счету, приложение вызывает деку CatalogCredit.hdml,в которой пользователю предлагается ввести информацию по его кредитнойкарте. Содержимое этой деки приведено ниже:

Как и в других деках, в CatalogCredit.hdml используются элементы дляуправления кнопками Edit (Редактировать) и Next (Следующий). Далее, в исходном коде следует элемент для предоставления пользователю возможности редактирования поля типа кредитной карты либо поля ее номера. Основываясь на выборе пользователя, приложение передает управление именованомуэлементу внутри деки, который предлагает пользователю ввести данные в определенном формате.

После ввода пользователем информации о кредитной карте приложение загружает файл CatalogDone.hdml, из которого запускается сценарий языка PerlCatalogOrderHDML.pl.


Этому сценарию передаются параметры, как показано ниже:

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=CatalogDone>

<Action Type=Soft1 Label=Reset Task=GO Dest=CatalogItem.hdml> <Action Type=Accept Label=Order Task=GO Method=Post PostData=$ItemNum&$ItemDesc:noesc&$ShipName: noesc&$ShipAddr1:noesc&ShipAddr2:noesc&$ShipCity: noesc&$ShipState&ShipZip&$ShipPhone&$BillName: noesc&$BillAddr1:noesc&$BillAddr2:noesc&$BillCity: noesc&$BillState&$BillZip&$BillPhone&$CartType: noesc&$CardNum Dest=../waplibcgi/CatalogOrderHDML.pl>

<br>Order form complete

</Display>

</HDML>

Как видите, в нашем случае используется единственое поле postdata, и параметры разделяются с помощью символа "амперсанд" (&).

Подробнее о приложении CatalogOrder

Подробнее о приложении CatalogOrder

Когда пользователь запускает приложение CatalogOrder, дека Catalogltem.wmlпредлагает ему ввести номер товара и его характеристики. После того как этаинформация будет введена, загружается другая дека (CatalogShip.wml) для получения информации об адресе отправки. Дека Catalogltem.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" forua="true"/>
</head>
<card id="OrderItem">
<do type="accept" label="Edit"> <noop /> </do>
<do type="options" label="Next"> <go href="CatalogShip.wml" /> </do>
<p align="center">
Catalog Order
</p>
<p align="left" mode="nowrap">
Item information
<select>
<option onpick="#GetItemNum">Item#: $(ItemNum)</option> <option onpick="#GetItemDesc">Item: $(ItemDesc)</option>
</select>
</p>
</card>
<card id="GetItemNum">
<do type="accept"> <go href="#OrderItem" /> </do>
<p align="left">
Item #: <input name="ItemNum" maxlength="5" format="N4N" />
</p>
</card>
<card id="GetItemDesc">
<do type="accept"> <go href="#OrderItem" /> </do>
<p align="left">
Item: <input name="ItemDesc" maxlength="15" format="M14M" />


</p>

</card>

</wml>

Так же как и во всех деках формата WML, первые два ее элемента сообщают браузеру, какую из версий спецификации WAP поддерживает данное приложение. Внашем случае WML-страница поддерживает версию 1.0 языка XML и версию 1.1описания типа документа (DTD), разработанного ассоциацией WAP Forum.

<?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" forua="true"/>

</head>

Элемент позволяет точно определить метаинформацию для исходногофайла. В нашем случае строка http-eguiv="Cache-Control" сообщает браузеруWAP, что эта часть метаинформации используется системой кэширования памяти. Аналогично, строка content=max-age=0 сообщает браузеру, что максимальноевремя, в течение которого будет кэшироваться этот файл, равно нулю секунд;значит, браузер не будет кэшировать данные, а загружать данные с сервера каждый раз, когда они будут запрошены. Для этой книги значение нуля было выбрано для содействия процессу обучения читателя. При выборе нуля каждый раз,когда будут происходить изменения, они будут передаваться на телефон. В реальном приложении статическое меню, подобное этому, можно использовать поумолчанию в течение 30 дней. Последняя строка forua="true" определяет, чтозначение Cache-Control предназначено для телефона и не может быть измененокаким-либо промежуточным агентом.


Приложение использует две переменные (itemNum и itemDesc) для хранениявведеных пользователем данных. После запуска приложения в карте используются два элемента . Один из них служит для преобразования надписи кнопкиподтверждения ввода Accept (Принять) из ОК по умолчанию в Edit (Редактировать) на время, пока на дисплеее отображаются выбранные опции. Второй элемент используется для обработки нажатия кнопки Next (Далее). :

Когда пользователь нажимает кнопку Next (Далее), приложение дает браузерууказание загрузить деку CatalogShip.wml, которая предлагает пользователю ввестиинформацию об адресе отправления товара.

Далее в карте используются элемент знак фунта (#), предшествующий первым двум опциямговорит о том, что каждая из карт, например #GetltemNum, находится внутри текущей деки формата WML. Когда пользователь производит выбор одной из опций, приложение передает управление соответствующей карте.

Внутри каждой из карт приложение использует элемент для предоставления пользователю возможности ввода необходимой .информации. Если выпроанализируете этот элемент, вы увидите, что поле format определяет форматсоответствующих данных. Например, в карте GetltemNum используетформат N4N для ограничения ввода пользователем от одного до пяти числовыхсимволов (N4N означает, что один числовой символ обязателен, остальные четыре-по необходимости).

После ввода пользователем номера товара и его описания приложение загружаетдеку CatalogShip.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" forua="true"/>

</head>

<card id="OrderShip">

<do type="accept" label="Edit"> <noop /> </do>

<do type="options" label="Next"> <go href="CatalogBill.wml" /> </do>

<p align="left" mode="nowrap">

Shipping information

<select>

<option onpick="#GetShipName"& gtShip to: $(ShipName)</option> <option onpick="#GetShipAddr1">Address: $(ShipAddr1)</option> <option onpick="#GetShipAddr2">Address: $(ShipAddr2)</option> <option onpick="#GetShipCity">City: $(ShipCity)</option> <option onpick="#GetShipState">State: $(ShipState)</option> <option onpick="#GetShipZip">Zip Code: $(ShipZip)</option> <option onpick="#GetShipPhone">Phone: $(ShipPhone)</option>

</select>

</p>

</card>

<card id="GetShipName">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

Ship to: <input name="ShipName" maxlength="15" format="M14M" />

</p>

</card>

<card id="GetShipAddr1">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

Address: <input name="ShipAddr1" maxlength="20" format="M19M" />

</p>

</card>

<card id="GetShipAddr2">


<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

Address: <input name="ShipAddr2" maxlength="20" format="M19M" />

</p>

</card>

<card id="GetShipCity">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

City: <input name="ShipCity" maxlength="15" format="M14M" />

</p>

</card>

<card id="GetShipState">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

State: <input name="ShipState" maxlength="2" format="AA" />

</p>

</card>

<card id="GetShipZip">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

Zip Code: <input name="ShipZip" maxlength="5" format="5N" />

</p>

</card>

<card id="GetShipPhone">

<do type="accept"> <go href="#OrderShip" /> </do>

<p align="left">

Phone: <input name="ShipPhone" maxlength="14" format="(NNN)-NNN-NNNN" />

</p>

</card>

</wml>

Дека CatalogShip.wml не сильно отличается от деки Catalogltem.wml, за исключением того, что в ней используется немногим больше карт, которые увеличивают

размер исходного кода внутри элемента для получения данных от пользователя.

После ввода пользователем адреса отправки товара, приложение загружает декуCatalogBill.wml, содержимое которой очень похоже на содержимое описаннойвыше деки. Далее приложение загружает деку CatalogCredit.wml для полученияинформации о кредитной карте пользователя. Исходный код декиCatalogCredit.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" forua="true"/>

</head>

<card id="CatalogCredit">

<do type="accept" label="Edit"> <noop /> </do>

<do type="options" label="Next"> <go href="CatalogDone.wml" /> </do>

<p align="left" mode="nowrap">

Credit Card

<select>

<option onpick="#GetCardType">Card: $(CardType)</option> <option onpick="#GetCardNum">Number: $(CardNum)</option>

</select>

</p>

</card>

<card id="GetCardType">

<do type="accept"> <go href="#CatalogCredit" /> </do>

<p align="left" mode="nowrap">

<select name="CardType">

<option value="AmEx">American Express</option> <option value="Discover">Discover</option> <option value="MasterCard">Master Card</option> <option value="Visa">Visa</option>

</select>

</p>


</card>

<card id="GetCardNum">

<do type="accept"> <go href="#CatalogCredit" /> </do>

<p align="left">

Number: <input name="CardNum" maxlength="19" format="NNNN-NNNN-NNNN-NNNN" />

</p>

</card>

</wml>

Дека использует элемент для отображениясписка кредитных карт. Аналогично, если выбран ввод номера карточки, приложение обращается к локальной карте GetCardNum, в которой используется элемент для предоставления пользователю возможности ввода номера кредитной карточки. Заметьте, что в элементе присутствует поле format.Использованием тире в поле формата приложение позволяет пользователю вводить номер карточки только стандартным способом. Для упрощения исходногокода в деке не предлагается вводить дату истечения срока действия кредитнойкарточки. Однако реализовать это можно точно так же, как в карте GetCardNum, стем лишь исключением, что формат вводимой информации в элементе должен иметь вид NN-NN.

После определения пользователем информации о кредитной карте приложениезагружает деку CatalogDone.wml, которая передает информацию о сделанном заказе сценарию языка Perl для обработки. Дека CatalogDone.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" forua="true"/>

</head>

<card id="CatalogDone">


<do type="options" label="Reset"> <go href="CatalogItem.wml" /> </do>

<do type="accept" label="Order">

<go method="post" href="../waplibcgi/CatalogOrderWML.pl"> <postfield name="ItemNum" value="$(ItemNum)&"/> <postfield name="ItemDesc" value="$(ItemDesc)&"/> <postfield name="ShipName" value="$(ShipName)&"/> <postfield name="ShipAddr1" value="$(ShipAddr1)&"/> <postfield name="ShipAddr2" value="$(ShipAddr2)&"/> <postfield name="ShipCity" value="$(ShipCity)&"/> <postfield name="ShipState" value="$(ShipState)&"/> <postfield name="ShipPhone" value="$(ShipPhone)&"/> <postfield name="BillName" value="$(BillName)&"/> <postfield name="BillAddr1" value="$(BillAddr1)&"/> <postfield name="BillAddr2" value="$(BillAddr2)&"/> <postfield name="BillCity" value="$(BillCity)&"/> <postfield name="BillState" value="$(BillState)&"/> <postfield name="BillPhone" value="$(BillPhone)&"/> <postfield name="CardType" value="$(CardType)&"/> <postfield name="CardNum" value="$(CardNum)"/> </go>

</do>

<p align="left" mode="nowrap">

Order form complete

</p>

</card>

</wml>

Для запуска сценария CatalogOrderWML.pl приложение использует элемент <до> с методом POST. Как вы видите, для передачи параметров сценарию используется элемент postfield, который позволяет приложению определить имя изначение.

Подробнее о сценарии языка Perl CatalogOrderHDML.pl

Подробнее о сценарии языка Perl CatalogOrderHDML.pl

Как и приложение формата WML, приложение формата HDML использует сценарий языка Perl для анализа введенной информации о заказе. Эту информациюсценарий получает из деки CatalogDone.hdml. После того, как будут проанализированы полученные данные, сценарий создает исходный код формата HDML,отображающий информацию о заказе. Исходный код сценарияCatalogOrderHDML.pl приведен ниже:
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$ItemNum = $data[0]; $ItemDesc = $data[1]; $ShipName = $data[2]; $ShipAddr1 = $data[3]; $ShipAddr2 = $data[4]; $ShipCity = $data[5]; $ShipState = $data[6]; $ShipZip = $data[7]; $ShipPhone = $data[8]; $BillName = $data[9]; $BillAddr1 = $data[10]; $BillAddr2 = $data[11]; $BillCity = $data[12]; $BillState = $data[13]; $BillZip = $data[14]; $BillPhone = $data[15]; $CardType = $data[16]; $CardNum = $data[17];
#Do processing here...
$Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display>
<Action Type=Accept Task=GO Dest=../CatalogOrder/CatalogItem.hdml>
Input data:<br><br>
\$ItemNum<br> \$ItemDesc<br><br> \$ShipName<br> \$ShipAddr1<br> \$ShipAddr2<br> \$ShipCity<br> \$ShipState<br> \$ShipZip<br> \$ShipPhone<br> \$BillName<br> \$BillAddr1<br> \$BillAddr2<br> \$BillCity<br> \$BillState<br> \$BillZip<br> \$BillPhone<br> \$CardType<br> \$CardNum
</Display>
</HDML>";
print $Deck;
Для проведения анализа данных, полученных с использованием функции $ENV,сценарий считывает всю информацию о переданных параметрах в переменную$Buffer. Далее, используя функцию разделения split (), переписывает параметры в массив (помните, что дека формата HDML поместила между параметрамисимвол &, который функция разделения использует для распознавания каждогоотдельного параметра). После этого значения элементов массива просто присваиваются соответствующим переменным. Строка внутри сценария, котораягласит Do processing here (Здесь происходит обработка) представляет область,где вы должны поместить исходный код для взаимодействия с существующимиприложениями для электронной коммерции вашей компании.


Подробнее о сценарии языка Perl CatalogOrderWML.pl

Подробнее о сценарии языка Perl CatalogOrderWML.pl

В реальном приложении сценарий языка Perl CatalogOrderWML.pl должен инициировать серию операций, таких, как подтверждение действительности номеракредитной карты, проверка списка базы данных (чтобы убедиться, что товардоступен), размещение текущего заказа в базе данных компании и так далее. Другими словами, сценарий должен взаимодействовать со средствами электроннойкоммерции компании. Таким образом, для большинства компаний создание подобного приложения, поддерживающего протокол WAP, заключается просто впостроении основанной на WML интерфейсной части для своего программногообеспечения электронной коммерции.
Сценарий CatalogOrderWML.pl просто анализирует переданные ему приложениемдля электронной коммерции параметры, создает новую деку формата WML, которую браузер использует для отображения транзакции. Исходный код сценарияCatalogOrderWML.pl приведен ниже:
#!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars();
$ItemNum = $cgiVars{"ItemNum"}; $ItemDesc = $cgiVars{"ItemDesc"}; $ShipName = $cgiVars{"ShipName"}; $ShipAddr1 = $cgiVars{"ShipAddr1"}; $ShipAddr2 = $cgiVars{"ShipAddr2"}; $ShipCity = $cgiVars{"ShipCity"}; $ShipState = $cgiVars{"ShipState"}; $ShipZip = $cgiVars{"ShipZip"};; $ShipPhone = $cgiVars{"ShipPhone"}; $BillName = $cgiVars{"BillName"}; $BillAddr1 = $cgiVars{"BillAddr1"}; $BillAddr2 = $cgiVars{"BillAddr2"}; $BillCity = $cgiVars{"BillCity"}; $BillState = $cgiVars{"BillState"}; $BillZip = $cgiVars{"BillZip"}; $BillPhone = $cgiVars{"BillPhone"}; $CardType = $cgiVars{"CardType"}; $CardNum = $cgiVars{"CardNum"};
#Do processing here...
$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card>

<do type=\"accept\"> <go href=\"../CatalogOrder/CatalogItem.wml\" /> </do>

<p align=\"left\" mode=\"nowrap\">

Input data:<br/><br/>

\$ItemNum<br/> \$ItemDesc<br/> \$ShipName<br/> \$ShipAddr1<br/> \$ShipAddr2<br/> \$ShipCity<br/> \$ShipState<br/> \$ShipZip<br/> \$ShipPhone<br/> \$BillName<br/> \$BillAddr1<br/> \$BillAddr2<br/> \$BillCity<br/> \$BillState<br/> \$BillZip<br/> \$BillPhone<br/> \$CardType<br/> \$CardNum

</p>

</card>

</wml>";

print $Deck;

Первая строка сценария представляет собой комментарий, сообщающий интерпретатору командной строки, где находится интерпретатор языка Perl. Втораястрока сообщает интерпретатору языка, что сценарий использует в своей работедругой сценарий языка Perl DeckUtils.pl, в котором определены процедуры дляанализа параметров. После анализа параметров сценарий создает и печатаетпростую деку формата WML, перехватывая которую браузер отображает итоговуюинформацию по сделанному заказу. Как минимум, сценарий должен проверить,введены ли пользователем имя, адрес, номер товара, номер кредитной карты итак далее. Для выполнения этих действий он просто проверяет переменные наналичие нулевого значения, и если значение какой-либо из переменных равнонулю, передает управление обратно соответствующей карте, открывая и выводядеку формата WML:

Приглашение к вводу адресадля отправки товара

Рисунок 15.2. Приглашение к вводу адресадля отправки товара

Приглашение к вводу адресадля отправки товара

Приглашение к вводу данныхкредитной карты

Рисунок 15.3. Приглашение к вводу данныхкредитной карты

Приглашение к вводу данныхкредитной карты

Приглашение к вводу номератовара и его описания

Рисунок 15.1. Приглашение к вводу номератовара и его описания

Приглашение к вводу номератовара и его описания

Рассмотрение приложения Restaurant

Приглашение на ввод данных о заказе

Рисунок 16.4. Приглашение на ввод данных о заказе

Приглашение на ввод данных о заказе

После ввода пользователем информации о заказе, приложение посылает введенные данные в Peri-сценарий, который в реальных условиях взаимодействовал быс базой данных по заказам в ресторане. Чтобы сформировать приглашение пользователю на ввод данных о заказе, приложение запускает сценарийRestReservationWML.pl, состоящий из следующего программного кода:
#!/usr/bin/perl
$RestName = $ENV{'QUERY_STRING'};
$RestName =~ s/%20/ /g;
{ $Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>
</head>
<card id=\"EditRes\">
<do type=\"accept\" label=\"Edit\"> <noop /> </do>
<do type=\"options\" label=\"Make\"> <go href=\"#MakeRes\" /> </do>
<p align=\"center\">
$RestName<br/>
</p>
<p align=\"left\" mode=\"nowrap\">
<select>
<option onpick=\"#GetDay\">Day: \$(ResDay)</option> <option onpick=\"#GetTime\">Time: \$(ResTime)</option> <option onpick=\"#GetNumber\">Number: \$(ResNumber)</option> <option onpick=\"#GetName\">Name: \$(ResName)</option>
</select>
</p>
</card>
<card id=\"GetDay\">
<do type=\"accept\"> <go href=\"#EditRes\" /> </do>
<p align=\"left\" mode=\"nowrap\">
<select name=\"ResDay\">


<option value=\"Sunday\">Sunday</option> <option value=\"Monday\">Monday</option> <option value=\"Tuesday\">Tuesday</option> <option value=\"Wednesday\">Wednesday</option> <option value=\"Thursday\">Thursday</option> <option value=\"Friday\">Friday</option> <option value=\"Saturday\">Saturday</option>

</select>

</p>

</card>

<card id=\"GetTime\">

<do type=\"accept\"> <go href=\"#EditRes\" /> </do>

<p align=\"left\">

Time: <input name=\"ResTime\" maxlength=\"5\" format=\"NN:NN\" />

</p>

</card>

<card id=\"GetNumber\">

<do type=\"accept\"> <go href=\"#EditRes\" /> </do>

<p align=\"left\">

Number in party: <input name=\"ResNumber\" maxlength=\"2\" format=\"*N\" />

</p>

</card>

<card id=\"GetName\">

<do type=\"accept\"> <go href=\"#EditRes\" /> </do>

<p align=\"left\">

Name: <input name=\"ResName\" maxlength=\"15\" format=\"M14M\" />

</p>

</card>

<card id=\"MakeRes\">

<do type=\"accept\" label=\"Done\"> <go href=\"../RestaurantRes/ RestaurantRes.wml\" /> </do>

<p align=\"left\" mode=\"nowrap\">

Reservation at<br/> $RestName<br/> Confirmed

</p>

</card>

</wml>"; }

print $Deck;

Сценарий попросту создает WML-страницу, которая принимает данные о заказе, вводимые пользователем. Для получения данных о заказе приложение использует Peri-сценарий (вместо того, чтобы просто вызвать существующий WML-код),так как в реальном приложении сценарий использовался бы для связи с базойданных и затем мгновенно создавал бы WML-карты. Как вы, вероятно, догадались,содержимое Peri-сценария RestReservationHDML.pl почти полностью совпадает сWML-сценарием, за исключением того, что данный сценарий создает HDML-страницу.


Рассмотрение приложения Restaurant.hdml

Рассмотрение приложения Restaurant.hdml

Как и приложение, основанное на WML, Restaurant.hdml позволяет отображатьадрес и номер телефона, используя для этого портативное устройство пользователя. Кроме того, при желании, пользователь также может автоматически позвонить в ресторан. Приложение Restauranthdml реализуется с помощью следующего программного кода на HDML:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=GetRestType Key=RestType>
<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$RestType Dest=../waplibcgi/RestCallTypeHDML.pl>
<Center>Restaurants
<CE Value="American">American <CE Value="Chinese">Chinese <CE Value="FastFood">Fast Food <CE Value="HealthFood">Health Food <CE Value="Italian">Italian <CE Value="Mexican">Mexican <CE Value="Seafood">Seafood
</Choice>
</HDML>
Первый элемент в файле сообщает браузеру (или другим программистам) информацию о версии спецификации HDML, поддерживаемой приложением. Крометого, параметр Markable=True определяет, что браузер может устанавливать наHDML-странице закладку (Bookmark), а параметр TTL=0 предписывает браузеру невыполнять кэширование HDML-страницы. Для предоставления пользователювозможности указывать тип предпочитаемой кухни приложение использует элемент . Затем приложение запускает Peri-сценарий RestCallTypeHDML.pl,чтобы отобразить на экране список названий ресторанов, из которых пользователь может сделать свой выбор. Peri-сценарий RestCallTypeHDML.pl реализуется спомощью следующего программного кода: #!/usr/bin/perl
read (STDIN, $RestType, $ENV{'CONTENT_LENGTH'});
if ($RestType eq "American")
{ $Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=GetAmerican Key=RestName>
<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallAmerHDML.pl>


<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>American<br>

<CE Value=AllStar& gtAll Star Cafe <CE Value=MarysDiner>Mary's Diner <CE Value=Timberline>Timberline Inn

</Choice>

</HDML>";

}

elsif ($RestType eq "Chinese")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetChinese Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallChineseHDML.pl>

<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Chinese<br>

<CE Value=ChinaGarden>China Garden <CE Value=GoldenDragon>Golden Dragon <CE Value=PlumTree>Plum Tree Inn

</Choice>

</HDML>";

}

elsif ($RestType eq "FastFood")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetFastFood Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallFastFoodHDML.pl>

<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Fast Food<br>

<CE Value=BurgerKing>Burger King <CE Value=McDonalds>McDonald's <CE Value=TopSpot>Top Spot

</Choice>

</HDML>";

}

elsif ($RestType eq "HealthFood")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetHealthFood Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallHealthFoodHDML.pl>


<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Health Food<br>

<CE Value=GeneralNutrition& gtGeneral Nutrition <CE Value=HealthExpress>Health Express <CE Value=LivingHealthy>Living Healthy

</Choice>

</HDML>";

}

elsif ($RestType eq "Italian")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetItalian Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallItalianHDML.pl>

<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Italian<br>

<CE Value=Marios>Mario's <CE Value=OliveGarden>Olive Garden <CE Value=PapaMurphys>Papa Murphy's

</Choice>

</HDML>";

}

elsif ($RestType eq "Mexican")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetMexican Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallMexicanHDML.pl>

<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Mexican<br>

<CE Value=BajaFresh>Baja Fresh <CE Value=Guadalajara>Guadalajara Grill <CE Value=LaVilla>La Villa

</Choice>

</HDML>";

}

elsif ($RestType eq "Seafood")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=GetSeafood Key=RestName>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=\$RestName Dest=RestCallSeafoodHDML.pl>


<Action Type=Soft1 Label=Back Task=GO Dest=../RestaurantCall/RestaurantCall.hdml>

<Center>Restaurants<br> <Center>Seafood<br>

<CE Value=KPSeafood>K & P Seafood <CE Value=FishCompany>Las Vegas Fish Company <CE Value=SevenSeas>Seven Seas

</Choice>

</HDML>";

}

print $Deck;

Сценарий анализирует параметр, после этого присваивает тип ресторана переменной $RestType. Далее программа использует серию ветвлений if-else дляопределения выбранного типа ресторана, в этом месте программного кода сценарий создает HDML-страницу, отображаемую браузером в виде списка соответствующих ресторанов. После выбора пользователем некоторого конкретного ресторана вновь созданная HDML-страница запускает соответствующий типу кухниPeri-сценарий, подобный RestCallSeafoodHDML.pl, приводимому здесь:

#!/usr/bin/perl

read (STDIN, $RestName, $ENV{'CONTENT_LENGTH'});

if ($RestName eq "KPSeafood")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=KPSeafood>

<Action Type=Soft1 Label=Back Task=GO Method=Post PostData=Seafood Dest=RestCallTypeHDML.pl>

<Action Type=Accept Icon=phone1 Label=Call Task=Call Number=702-555-1212>

<Center>Restaurants<br> <Center>Seafood<br> <Line>K & P Seafood<br> 111 Main Street<br> Las Vegas, NV<br> 702-555-1212

</Display>

</HDML>"; }

elsif ($RestName eq "FishCompany")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=FishCompany>

<Action Type=Soft1 Label=Back Task=GO Method=Post PostData=Seafood Dest=RestCallTypeHDML.pl>

<Action Type=Accept Icon=phone1 Label=Call Task=Call Number=702-555-1212>

<Center>Restaurants<br> <Center>Seafood<br> <Line>Las Vegas Fish Company<br> 222 East Sahara<br> Las Vegas, NV<br> 702-555-1212


</Display>

</HDML>"; }

elsif ($RestName eq "SevenSeas")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=SevenSeas>

<Action Type=Soft1 Label=Back Task=GO Method=Post PostData=Seafood Dest=RestCallTypeHDML.pl>

<Action Type=Accept Icon=phone1 Label=Call Task=Call Number=702-555-1212>

<Center>Restaurants<br> <Center>Seafood<br> <Line>Seven Seas<br> 100 Water Street<br> Las Vegas, NV<br> 702-555-1212

</Display>

</HDML>"; }

print $Deck;

Элемент с параметром Task= Call определяет номер, который будетвызывать браузер, когда пользователь нажимает кнопку ввода (Accept), на которой может быть нанесено слово Call (Вызов) или, если телефон поддерживаетпиктограммы, изображение телефона.

Рассмотрение приложения Restaurant

Рассмотрение приложения Restaurant

При запуске пользователем приложения Restaurant WML-страницаRestaurantCall.wml отображает список разных типов ресторанов и выводит приглашение пользователю на выбор типа предпочитаемой кухни. WML-страницаRestaurantCall.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" forua="true"/>
</head>
<card id="GetRestType">
<do type="accept" label="Pick"> <go href="../waplibcgi/RestCallTypeWML.pl ?$(RestType)" /> </do>
<p align="center">
Restaurants
</p>
<p align="left">
<select name="RestType">
<option value="American">American</option> <option value="Chinese">Chinese</option> <option value="FastFood">Fast Food</option> <option value="HealthFood">Health Food</option> <option value="Italian">Italian</option> <option value="Mexican">Mexican</option> <option value="Seafood">Seafood</option>
</select>
</p>
</card>
</wml>
Первые два элемента WML-страницы сообщают WAP-браузерам версию WAP-спецификации, которую поддерживает приложение. В данном случае WML-страница совместима с XML 1.0 и описанием типа документа (DTD) версии 1.1,разработанным ассоциацией WAP Forum. Любая WML-страница, размещаемаяпосле информации о версии, начинается с тега . В конце каждой WML-страницы должен находиться соответствующий тег , который завершаетэлементы WML-страницы.


Теги и , располагающиеся после тега, позволяют указывать данные о WML-странице, включая метаданные и информацию, управляющую доступом.

Элемент позволяет определять для WML- страницы метаинформацию. Внашем случае параметр http-equiv=Cache-Control сообщает WAP-браузеру, чтоданная часть метаинформации относится к системе кэширования памяти. Аналогично, параметр content=max-age=0 сообщает браузеру, что максимальное время, в течение которого должно выполняться кэширование WML-страницы, равнонулю секунд; то есть, браузер должен не запоминать, а повторно загружать данные с сервера каждый раз, когда поступает запрос. Для данной книги нулевоезначение было выбрано, чтобы помочь читателю в разработке программы. Привыборе нулевого значения каждый раз, когда происходит изменение, оно передается на телефон. В реально эксплуатируемом приложении статическое меню,подобное рассматриваемому здесь, по-видимому, должно использовать интервалхранения, установленный по умолчанию, равным 30 дням. Наконец, параметрforua="true" определяет, что данное значение Cache-Control, управляющеекэшированием, предназначено для телефона и не должно удаляться каким-либопромежуточным агентом.

Для отображения разных типов ресторанов WML-страница использует элемент, который обеспечиваетвозможность выбора для редактирования числа постояльцев, даты заселения илидаты выселения. В зависимости от сделанного пользователем выбора выполняется ветвление программного кода и переход на локальную карту, содержащую элемент , который выводит приглашение пользователю на ввод данных. Поле format, присутствующее внутри каждого элемента , определяет формат данных, воспринимаемых приложением. После ввода пользователем требуемых данных приложение вызывает Peri-сценарий CheckAvailWML.pl, отображающий на экране обобщенную информацию по свободным номерам.

В реальном приложении сценарий CheckAvailWML.pl взаимодействовал бы с базой данных, чтобы определить наличие свободных номеров.Затем сценарийсортировал бы свободные номера по типу гостиницы и предоставлял бы пользователю возможность зарезервировать номер из выводимого списка. Для простоты сценарий, запускаемый приложением Hotellnfo, отображает один и тот же список гостиничных номеров, независимо от выбранной гостиницы или введенныхрегистрационных данных.

Рассмотрение приложения Hotel Info

Рассмотрение приложения Hotel Info

При запуске приложения Hotellnfo WML-страница Hotellnfo.wml отображает списокгородов и выводит приглашение пользователю на выбор требуемого города. После выбора пользователем города выполняется ветвление программного кода ивыводится приглашение на выбор в городе определенной гостиницы. WML-страница Hotellnfo.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" forua="true"/>
</head>
<card id="Hotel">
<do type="accept" label="Pick"> <noop /> </do>
<p align="center">
Web Inns<br/>
</p>
<p align="left" mode="nowrap">
<select>
<option onpick="#LasVegas">Las Vegas</option> <option onpick="#LosAngeles">Los Angeles</option> <option onpick="#Orlando">Orlando< /option> <option onpick="#SanFrancisco">San Francisco</option> <option onpick="#WashingtonDC">Washington DC</option>
</select>
</p>
</card>
<card id="LasVegas">
<do type="accept" label="Pick"> <go href="../waplibcgi/HotelAvailWML.pl ?$(HotelCode)" /> </do>
<do type="prev" label="City"> <prev /> </do>
<p align="center">
Web Inns<br/> Las Vegas
</p>
<p align="left" mode="nowrap">


<select name="HotelCode">

<option value="LVAirport">Airport</option> <option value="LVNorth">North</option> <option value="LVSouth">South</option> <option value="LVCenter">City Center</option>

</select>

</p>

</card>

<card id="LosAngeles">

<do type="accept" label="Pick"> <go href="../waplibcgi/HotelAvailWML.pl ?$(HotelCode)" /> </do>

<do type="prev" label="City"> <prev /> </do>

<p align="center">

Web Inns<br/& gt Los Angeles

</p>

<p align="left" mode="nowrap">

<select name="HotelCode">

<option value="LAAirport">Airport</option> <option value="LANorth">North</option> <option value="LASouth">South</option> <option value="LACenter">City Center</option>

</select>

</p>

</card>

<card id="Orlando">

<do type="accept" label="Pick"> <go href="../waplibcgi/HotelAvailWML.pl ?$(HotelCode)" /> </do>

<do type="prev" label="City"> <prev /> </do>

<p align="center">

Web Inns<br/> Orlando

</p>

<p align="left" mode="nowrap">

<select name="HotelCode">

<option value="ORAirport">Airport</option> <option value="ORNorth">North</option> <option value="ORSouth">South</option> <option value="ORCenter">City Center</option>


</select>

</p>

</card>

<card id="SanFrancisco">

<do type="accept" label="Pick"> <go href="../waplibcgi/HotelAvailWML.pl ?$(HotelCode)" /> </do>

<do type="prev" label="City"> <prev /> </do>

<p align="center">

Web Inns<br/> San Francisco

</p>

<p align="left" mode="nowrap">

<select name="HotelCode">

<option value="SFAirport">Airport</option> <option value="SFNorth">North</option> <option value="SFSouth">South</option> <option value="SFCenter">City Center</option>

</select>

</p>

</card>

<card id="WashingtonDC">

<do type="accept" label="Pick"> <go href="../waplibcgi/HotelAvailWML.pl ?$(HotelCode)" /> </do>

<do type="prev" label="City"> <prev /> </do>

<p align="center">

Web Inns<br/> Washington, DC

</p>

<p align="left" mode="nowrap">

<select name="HotelCode">

<option value="DCAirport">Airport</option> <option value="DCNorth">North</option> <option value="DCSouth">South</option> <option value="DCCenter">City Center</option>

</select>

</p>

</card>

</wml>

Первые два элемента WML-страницы сообщают WAP-браузерам версию WAP-спецификации, которую поддерживает приложение. В данном случае WML-страница совместима с XML 1.0 и описанием типа документа (DTD) версии 1.1,разработанным ассоциацией WAP Forum.


Любая WML-страница, размещаемаяпосле информации о версии, начинается с тега <имя>. В конце каждой WML- страницы должен находиться соответствующий тег
, который завершаетэлементы WML-страницы. Теги <НЕAD> и , располагающиеся после тега, позволяют указывать данные о WML-странице, включая метаданные и информацию, управляющую доступом.

Элемент позволяет определять для WML-страницы метаинформацию. В нашем случае параметр http-equiv=Cache-Control сообщает WAP-браузеру, чтоданная часть метаинформации относится к системе кэширования памяти. Аналогично, параметр content=max-age=0 сообщает браузеру, что максимальное время, в течение которого должно выполняться кэширование WML-страницы, равнонулю секунд; то есть, браузер должен не запоминать, а повторно загружать данные с сервера каждый раз, когда поступает запрос. Для данной книги нулевоезначение было выбрано, чтобы помочь читателю в разработке программы. Привыборе нулевого значения каждый раз, когда происходит изменение, это изменение передается на телефон. В реально эксплуатируемом приложении статическое меню, подобное рассматриваемому здесь, по-видимому, должно использовать интервал хранения, установленный по умолчанию, равным 30 дням. Наконец, параметр forua="true" определяет, что данное значение Cache-Controlпредназначено для телефона и не должно удаляться каким-либо промежуточнымагентом

Для отображения списка городов WML-страница использует элемент , на выбор конкретной гостиницы. После выбора пользователем гостиницы приложение вызывает Perl-сценарий HotelAvailWML.pl, формирующий на экране приглашение пользователюна ввод данных о регистрации в гостинице.

Рассмотрение приложения HotelInfo.hdml

Рассмотрение приложения HotelInfo.hdml

Как и приложение на основе WML, Hotellnfo.hdml предоставляет пользователювозможность выбирать гостиницу и затем вводить регистрационные данные.Приложение Hotellnfo.hdml реализуется с помощью следующего программного
кода на HDML:
<HDML Version=3.0 Markable=True TTL=0>
<Choice Name=Hotel>
<Action Type=Accept Label=Pick>
<Center>Web Inns<br>
<CE Task=GO Dest=#LasVegas>Las Vegas <CE Task=GO Dest=#LosAngeles>Los Angeles <CE Task=GO Dest=#Orlando>Orlando <CE Task=GO Dest=#SanFrancisco>San Francisco <CE Task=GO Dest=#WashingtonDC>Washington DC
</Choice>
<Choice Name=LasVegas Key=HotelCode>
<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$(HotelCode) Dest=../waplibcgi/HotelAvailHDML.pl>
<Action Type=Prev Label=City>
<Center>Web Inns<br> <Center>Las Vegas
<CE Value="LVAirport">Airport <CE Value="LVNorth">North <CE Value="LVSouth">South <CE Value="LVCenter">City Center
</Choice>
<Choice Name=LosAngeles Key=HotelCode>
<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$(HotelCode) Dest=../waplibcgi/HotelAvailHDML.pl>
<Action Type=Prev Label=City>
<Center>Web Inns<br> <Center>Los Angeles
<CE Value="LAAirport">Airport <CE Value="LANorth">North <CE Value="LASouth">South <CE Value="LACenter">City Center
</Choice>
<Choice Name=Orlando Key=HotelCode>
<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$(HotelCode) Dest=../waplibcgi/HotelAvailHDML.pl>
<Action Type=Prev Label=City>
<Center>Web Inns<br> <Center>Orlando


<CE Value="ORAirport">Airport <CE Value="ORNorth">North <CE Value="ORSouth">South <CE Value="ORCenter">City Center

</Choice>

<Choice Name=SanFrancisco Key=HotelCode>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$(HotelCode) Dest=../waplibcgi/HotelAvailHDML.pl>

<Action Type=Prev Label=City>

<Center>Web Inns<br> <Center>San Francisco

<CE Value="SFAirport">Airport <CE Value="SFNorth">North <CE Value="SFSouth">South <CE Value="SFCenter">City Center

</Choice>

<Choice Name=WashingtonDC Key=HotelCode>

<Action Type=Accept Label=Pick Task=GO Method=Post PostData=$(HotelCode) Dest=../waplibcgi/HotelAvailHDML.pl>

<Action Type=Prev Label=City>

<Center>Web Inns<br> <Center>Washington, DC

<CE Value="DCAirport">Airport <CE Value="DCNorth">North <CE Value="DCSouth">South <CE Value="DCCenter">City Center

</Choice>

</HDML>

Первый элемент в файле сообщает браузеру (или другим программистам) информацию о версии спецификации HDML, поддерживаемой приложением. Крометого, параметр Markable=True определяет, что браузер может устанавливать наHDML-странице закладку, а параметр TTL=0 предписывает браузеру не выполнятькэширование HDML-страницы. Для обеспечения возможности выбора требуемого

города приложение использует элемент . На основе сделанного пользователем выбора выполняется ветвление программного кода и переход на второйэлемент , обеспечивающий возможность выбора гостиницы. После тогокак пользователь указывает конкретную гостиницу, приложение запускает Peri-сценарий HotelAvailHDML.pl, который выводит на экран приглашение пользователю на ввод регистрационных данных.

Рассмотрение приложения YellowPages

Отображение на экране списка компаний отвечающих условиям поиска

Рисунок 18.3. Отображение на экране списка компаний отвечающих условиям поиска

Отображение на экране списка компаний отвечающих условиям поиска

Приглашение для ввода местонахождения компании

Рисунок 18.2. Приглашение для ввода местонахождения компании

Приглашение для ввода местонахождения компании

Приглашение для ввода названия компании или профиля ее деятельности

Рисунок 18.1. Приглашение для ввода названия компании или профиля ее деятельности

Приглашение для ввода названия компании или профиля ее деятельности

Рассмотрение Peri-сценария YellowPagesWML.pl

Рассмотрение Peri-сценария YellowPagesWML.pl

После того как пользователь указывает данные о компании в приложенииYellowPages, программа запускает Peri-сценарий для поиска и нахождения компаний, отвечающих введенным требованиям. В реальном приложении сценарийвзаимодействовал бы с базой данных для получения компаний, данные которыхсоответствуют условиям поиска. Затем сценарий создавал бы WML-карты, обеспечивающие отображение на экране результатов поиска в удобном виде. Следующий сценарий, YellowPagesWML.pl, формирует одни и те же результаты поиска, независимо от данных запроса (из-за отсутствия доступной базы данных с адресами компаний). Тем не менее, вы должны отметить для себя, что сценарийсоздает карты, которые для обеспечения возможности автоматического звонка вкомпанию, отображаемую на экране сотового телефона пользователя, используют функции интерфейса приложений для беспроводной телефонной связи(WTAI - Wireless Telephony Application Interface). Кроме того, при просмотре информации по нескольким компаниям приложение может выполнять циклические перемещения, во многом напоминающие навигацию по списку с гиперсвязями. Peri-сценарий YellowPagesWML.pl реализуется с помощью следующего программного кода:
#!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars(); $BizName = $cgiVars{"BizName"}; $ZipCode = $cgiVars{"ZipCode"}; $CityName = $cgiVars{"CityName"}; $StateName = $cgiVars{"StateName"}; $Online = $cgiVars{"Online"};
#Do processing here...
$Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>
</head>
<card id=\"Result1\">
<do type=\"accept\" label=\"Next\"> <go href=\"#Result2\" /> </do>


<p align=\"left\" mode=\"nowrap\">

Bridget's Boutique<br/> 1234 Main Street<br/> Cedar City, UT<br/> <a href=\"wtai://wp/mc;14355551212\" title=\"Call\">1-435-555-1212</a>

</p>

</card>

<card id=\"Result2\">

<do type=\"accept\" label=\"Next\"> <go href=\"#Last\" /> </do>

<p align=\"left\" mode=\"nowrap\">

Abigail's Antiques<br/> 1234 Main Street<br/> Cedar City, UT<br/> <a href=\"wtai://wp/mc;14355551212\" title=\"Call\">1-435-555-1212</a>

</p>

</card>

<card id=\"Last\">

<do type=\"accept\" label=\"Done\"> <go href=\"http://waplib.com/YellowPages /YellowPages.wml\" /> </do>

<p align=\"left\" mode=\"wrap\">

For purposes of this example all lookups return the same results.

</p>

</card>

</wml>";

print $Deck;

Работа сценария начинается с анализа параметров, передаваемых ему WML-страницей YellowPages.wml. Далее, строка Do processing here (Выполнять обработку здесь) соответствует месту, где сценарий в обычных условиях взаимодействовал бы с программой базы данных.

Затем сценарий создает три WML-карты с именами Resultl (Результат!), Result2и Last (Последняя). Приложение вначале выводит на экран карту Resultl, отображающую экранную кнопку Next (Далее). Если пользователь выберет кнопкуNext (Далее), приложение загрузит карту Result2. Карта Result2 также отображает кнопку Next (Далее), которая предоставляет связь с картой Last. Если вывыберете карту Last, то обнаружите, что она отображает кнопку Done (Выполнено), возвращающую пользователя обратно в начало приложения YellowPages.

Внутри каждой карты приложения присутствует элемент анкера <а>, которыйобеспечивает возможность автоматической связи с компанией по сотовому телефону:

Код wp определяет, что функция находится в общей библиотеке, а код тс представляет собой имя выполняемой функции (make call - вызов по телефону).

Рассмотрение Perl-сиенария YellowPagesHDML.pl

Рассмотрение Perl-сиенария YellowPagesHDML.pl

Как и в случае приложения на WML, сценарий YellowPagesHDML.pl не взаимодействует с базой данных, содержащей названия компаний. Не имея такой возможности, сценарий создает данные по ряду компаний, названия которых пользователь может прокручивать на экране. Так же, как и в случае приложения на WML,пользователь может выделять номер телефона компании и автоматически набирать номер. Peri-сценарий YellowPagesHDML.pl реализуется с помощью следующего программного кода:
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$BizName = $data[0]; $ZipCode = $data[1]; $CityName = $data[2]; $StateName = $data[3]; $Online = $data[4];
#Do processing here...
$Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Results1>
<Action Type=Accept Task=GO Dest=#Results2 Label=Next> <Action Type=Soft1 Label=Call Task=Call Number=1-435-555-1212> <Line>Bridget's Boutique<br> 1234 Main Street<br> Cedar City, UT<br> 1-435-555-1212
</Display>
<Display Name=Results2>
<Action Type=Accept Task=GO Dest=#Last Label=Next> <Action Type=Soft1 Label=Call Task=Call Number=1-435-555-1212> <Line>Abigail's Antiques<br> 1234 Main Street<br> Cedar City, UT<br> 1-435-555-1212
</Display>
<Display Name=Last>
<Action Type=Accept Task=GO Label=Done Dest=http://waplib.com/YellowPages/YellowPages.hdml Vars=BizName=&ZipCode=&CityName=&StateName=&Online=>
For purposes of this example all lookups return the same results.
</Display>
</HDML>";
print $Deck;
Сценарий создает три информационных модуля Resultl (Результат!), Result2 иLast (Последний). Если вы рассмотрите элемент , присутствующийвнутри каждого информационного модуля, то обнаружите метку Next (Далее), спомощью которой выполняется передача управления на последующую карту.Внутри информационного модуля Last вы обнаружите метку Done (Выполнено),которая служит для повторной загрузки приложения YellowPages.


Рассмотрение приложения YellowPages.hdml

Рассмотрение приложения YellowPages.hdml

Как и приложение на WML, YellowPages.hdml предоставляет пользователювозможности поиска компании по названию, городу и штату, почтовому коду (zip)или электронному адресу. Для выполнения большей части обработки приложение использует Peri-сценарий. Приложение YellowPages.hdml реализуется с помощью следующего программного кода на HDML:
<HDML Version=3.0 Markable=True TTL=0>
<Entry Name=Start Format=15M Key=BizName Default="">
<Action Type=Accept Task=GO Dest=#GetSearch>
<Center>Yellow Pages <br><br>Search for: <br>(Name or type)
</Entry>
<Choice Name=GetSearch Method=Alpha>
Location:
<CE Task=GO Dest=#ZipCode>Zip Code <CE Task=GO Dest=#City>City/State <CE Task=GO Dest=#GetInfo Vars=ZipCode=&CityName=&StateName=&Online=True>Online
</Choice>
<Entry Name=ZipCode Format=NNNNN Key=ZipCode Default="">
<Action Type=Accept Task=GO Dest=#GetInfo Vars=CityName=&StateName=&Online=> Enter Zip Code:
</Entry>
<Entry Name=City Format=15M Key=CityName Default="">
<Action Type=Accept Task=GO Dest=#State Vars=ZipCode=&Online=> Enter City:
</Entry>
<Entry Name=State Format=AA Key=StateName Default="">
<Action Type=Accept Task=GO Dest=#GetInfo> Enter State:
</Entry>
<Display Name=GetInfo>
<Action Type=Accept Task=GO Label=Find Method=Post PostData=$(BizName:noesc)&$(ZipCode)&$ (CityName:noesc)&$(StateName)&$(Online) Dest=../waplibcgi/YellowPagesHDML.pl>
Search for:<br> Business: $BizName<br> Zip Code: $ZipCode<br> City/St: $CityName$StateName<br> Online: $Online
</Display>
</HDML>
Первый элемент в файле сообщает браузеру (или другим программистам) информацию о версии спецификации HDML, поддерживаемой приложением. Крометого, параметр Markable=True определяет, что браузер может устанавливать наHDML-странице закладку, а параметр TTL=0 предписывает браузеру не выполнятькэширование HDML-страницы.
Приложение начинается с элемента , обеспечивающего отображениеприглашения пользователю на ввод наименования компании. Затем приложениеиспользует элемент , который, при наличии у пользователя желания,позволяет вести поиск по почтовому коду (zip), городу и штату или по электронному адресу. На основе введенной информации выполняется ветвление программного кода и переход на именованный элемент , отображающийприглашение пользователю на ввод соответствующих данных. После того какпользователь введет необходимую информацию, выполняется ветвление программного кода приложения и переход на элемент Getlnfo, который, в своюочередь, запускает Peri-сценарий YellowPagesHDML.pl, чтобы обработать данные,введенные пользователем.

Рассмотрение приложения YellowPages

Рассмотрение приложения YellowPages

При запуске приложения YellowPages WML-страница YellowPages.wml выводит наэкран приглашение пользователю на ввод названия компании или рода ее деятельности. Затем пользователю предоставляется возможность указать почтовыйкод (zip), город, штат или электронный адрес. После ввода всех данных, необходимых для поиска, приложение запускает Peri-сценарий, который обрабатываетвведенную информацию. WML-страница YellowPages.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" forua="true"/>
</head>
<card>
<onevent type="onenterforward">
<refresh>
<setvar name="BizName" value="" /> <setvar name="Online" value="True" />
</refresh>
</onevent>
<onevent type="onenterbackward">
<refresh>
<setvar name="Online" value="True" />
</refresh>
</onevent>
<p align="center">
Yellow Pages<br/>
</p>
<p align="left">
Search for:<br/> (Name or type) <input name="BizName" maxlength="15" />
</p>
<p align="left">
Location:<br/>
<select> <option onpick="#ZipCode">Zip Code</option> <option onpick="#CityState">City /State</option> <option onpick="#GetInfo">Online< /option> </select>
</p>
</card>
<card id="ZipCode">


<onevent type="onenterforward">

<refresh>

<setvar name="ZipCode" value="" /> <setvar name="CityName" value="" /> <setvar name="StateName" value="" /> <setvar name="Online" value="" />

</refresh>

</onevent>

<onevent type="onenterbackward">

<refresh>

<setvar name="ZipCode" value="" /> <setvar name="CityName" value="" /> <setvar name="StateName" value="" /> <setvar name="Online" value="" />

</refresh>

</onevent>

<do type="accept"> <go href="#GetInfo" /> </do>

<p align="left">

Enter Zip Code: <input name="ZipCode" maxlength="5" format="NNNNN" />

</p>

</card>

<card id="CityState">

<onevent type="onenterforward">

<refresh>

<setvar name="ZipCode" value="" /> <setvar name="CityName" value="" /> <setvar name="StateName" value="" /> <setvar name="Online" value="" />

</refresh>

</onevent>

<onevent type="onenterbackward">

<refresh>

<setvar name="ZipCode" value="" /> <setvar name="CityName" value="" /> <setvar name="StateName" value="" /> <setvar name="Online" value="" />

</refresh>

</onevent>

<do type="accept"> <go href="#GetInfo" /> </do>


<p align="left">

Enter City: <input name="CityName" maxlength="15" format="*M" /><br/> Enter State: <input name="StateName" maxlength="2" format="AA" />

</p>

</card>

<card id="GetInfo">

<do type="accept" label="Find">

<go method="post" href="../waplibcgi/YellowPagesWML.pl"> <postfield name="BizName" value="$(BizName)&"/> <postfield name="ZipCode" value="$(ZipCode)&"/> <postfield name="CityName" value="$(CityName)&"/> <postfield name="StateName" value="$(StateName)&"/> <postfield name="Online" value="$(Online)"/> </go>

</do>

<p align="left" mode="nowrap">

Search for:<br/> Business: $(BizName)<br/> Zip Code: $(ZipCode)<br/> City/St: $(CityName)$(StateName)<br/> OnLine: $(Online)

</p>

</card>

</wml>

Первые два элемента WML-страницы сообщают WAP-браузерам версию WAP-спецификации, которую поддерживает приложение. В данном случае WML-страница совместима с XML 1.0 и описанием типа документа (DTD) версии 1.1, разработанным ассоциацией WAP Forum. Любая WML-страница, размещаемаяпосле информации о версии, начинается с тега . В конце каждой WML-страницы должен находиться соответствующий тег , который завершаетэлементы WML-страницы. Теги <НЕAD" и , располагающиеся после тега, позволяют указывать данные о WML-странице, включая метаданные и информацию, управляющую доступом.

Элемент позволяет определять для WML-страницы метаинформацию. Внашем случае параметр http-equiv=Cache-Control сообщает WAP-браузеру, чтоданная часть метаинформации относится к системе кэширования памяти.


Аналогично, параметр content=max-age= 0 сообщает браузеру, что максимальное время, в течение которого должно выполняться кэширование WML-страницы, равнонулю секунд; то есть, браузер должен не запоминать, а повторно загружать данные с сервера каждый раз, когда поступает запрос. Для данной книги нулевоезначение было выбрано, чтобы помочь читателю в разработке программы. Привыборе нулевого значения каждый раз, когда происходит изменение, оно передается на телефон. В реально эксплуатируемом приложении статическое меню,подобное рассматриваемому здесь, по-видимому, должно использовать интервалхранения, установленный по умолчанию, равным 30 дням. Наконец, параметр

forua="true" определяет, что данное значение Cache-Control предназначенодля телефона и не должно удаляться каким-либо промежуточным агентом.

Если взглянуть на элементы WML-страницы, то можно обнаружить элемент, который формирует приглашение пользователю на ввод наименованиякомпании. После ввода пользователем наименования компании приложение использует элемент для приема соответствующих данных.Наконец, после ввода всех данных выполняется ветвление программного кода ипереход на карту Getinfo, которая запускает Peri-сценарий YellowPagesWML.pl,чтобы обработать введенную информацию.

Рассмотрение приложения Real Estate

Отображение на экране данных о доме

Рисунок 19.3. Отображение на экране данных о доме

Отображение на экране данных о доме

Отображение списка домов,чья цена попадает в указанный пользователем диапазон

Рисунок 19.2. Отображение списка домов,чья цена попадает в указанный пользователем диапазон

Отображение списка домов,чья цена попадает в указанный пользователем диапазон

Приглашение пользователюна ввод ценового диапазона

Рисунок 19.1. Приглашение пользователюна ввод ценового диапазона

Приглашение пользователюна ввод ценового диапазона

Рассмотрение Peri-сценария RealEstateHDML.pl

Рассмотрение Peri-сценария RealEstateHDML.pl

Как и в случае приложения на WML, сценарий RealEstateHDML.pl не взаимодействует с базой данных, содержащей информацию о недвижимости. Вместо этогоиспользуются данные пяти домов, для которых известны цены и информация опродаже. Peri-сценарий RealEstateHDML.pl реализуется с помощью следующегопрограммного кода:
#!/usr/bin/perl
read (STDIN, $Buffer, $ENV{'CONTENT_LENGTH'});
@data = split(/&/, $Buffer);
$PriceLow = $data[0]; $PriceHigh = $data[1];
$Price1 = 99500; $Price2 = 149995; $Price3 = 249995; $Price4 = 500000; $Price5 = 1500000;
if (($PriceLow <= 0) ($PriceHigh <= 0) ($PriceLow > $PriceHigh))
{ $Deck = "Content-type: text/x-hdml
<HDML Version=3.0 Markable=True TTL=0>
<Display Name=Error>
<Action Type=Accept Label=Back Task=GO Dest=../RealEstate/RealEstate.hdml>
<Wrap>Error in price range. Please enter a minimum price and a maximum price.
</Display>
</HDML>";
}
else
{
$Option = "";
if (($Price1 >= $PriceLow) && ($Price1 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/GV01234.hdml>GV01234 &dol;99,500"; }
if (($Price2 >= $PriceLow) && ($Price2 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV01234.hdml>LV01234 &dol;149,995"; }
if (($Price3 >= $PriceLow) && ($Price3 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV77711.hdml>LV77711 &dol;249,995"; }
if (($Price4 >= $PriceLow) && ($Price4 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/BC01234.hdml>BC01234 &dol;500,000"; }
if (($Price5 >= $PriceLow) && ($Price5 <= $PriceHigh)) { $Option = $Option . "<CE Task=GO Dest=../RealEstate/LV11711.hdml>LV11711 &dol;1,500,000"; }


if ($Option eq "")

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=Error>

<Action Type=Accept Label=Back Task=GO Dest=../RealEstate/RealEstate.hdml>

<Wrap& gtNo houses match the price range.

</Display>

</HDML>";

}

else

{ $Deck = "Content-type: text/x-hdml

<HDML Version=3.0 Markable=True TTL=0>

<Choice Name=Pick>

<Action Type=Accept Label=View> <Action Type=Soft1 Label=Back Task=GO Dest=../RealEstate/RealEstate.wml>

<Line>Pick a house<br> ...MLS#....Price..

" . $Option . "

</Choice>

</HDML>"; }

}

print $Deck;

Как можно видеть, сценарий использует пять переменных, от $Pricel до$Price5, чтобы отслеживать цены домов, которые известны сценарию. Как и впредыдущем сценарии, для определения факта попадания цены дома в указанныйдиапазон, в программном коде используется серия операторов if. После того какпросмотрены цены всех пяти домов, приложение формирует HDML-страницу, которая с помощью элемента создает меню из опций, отвечающих условиям поиска (опции сценарий сохраняет в переменной $0ption). Когда пользователь позднее выбирает из списка некоторый конкретный дом, HDML-приложение загружает HDML-страницу, соответствующую выбранному дому. Например, файл 77711 .hdml содержит следующий программный код:

<HDML Version=3.0 Markable=True TTL=0>

<Display Name=House>

<Action Type=Accept Label=Back Task=PREV>

<Line>MLS #:LV77711<br> &dol;249,995<br> Las Vegas<br> 4 BR / 2 Ba<br> 4100 SF<br> <A Task=GOSUB Dest=#MoreInfo>More Info</A>

</Display>

<Display Name=MoreInfo>

<Action Type=Accept Label=Back Task=RETURN>

<Line>Lot Size: 400X400<br> Year Built: 1998<br> Fireplace: Yes<br> Patio: Yes<br> Pool: Yes<br> Spa: Yes

</Display>

</HDML>

Когда HDML-страница запускает первую карту, браузер выполняет программныйкод, располагающийся внутри элемента House. Если пользователь выбирает опцию More Information (Дополнительная информация), выполняется ветвлениепрограммного кода и переход (с использованием задания GOSUB) на элементMorelnfо.


Рассмотрение приложения Real Estate

Рассмотрение приложения Real Estate

При запуске приложения RealEstate WML-страница RealEstate.wml выводит на экран приглашение пользователю на ввод минимальной и максимальной цены надом. Затем, чтобы обработать введенные данные, приложение запускает Perl-сценарий. WML-страница RealEstate.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" forua="true"/>
</head>
<card id="RealEstatePrice">
<onevent type="onenterbackward">
<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value="$(PriceLow)&"/> <postfield name="PriceHigh" value="$(PriceHigh)&"/> </go>
</onevent>
<do type="accept" label="Edit"> <noop /> </do>
<do type="options" label="Find"> <go href="#GetRealEstateResults" /> </do>
<p align="center">
Real Estate<br/> Listings<br/>
</p>
<p align="left">
Price Range:
<select>
<option onpick="#GetPriceLow">Low $$$(PriceLow)</option> <option onpick="#GetPriceHigh">High $$$(PriceHigh)</option>
</select>
</p>
</card>
<card id="GetPriceLow">
<do type="accept"> <go href="#RealEstatePrice" /> </do>
<p align="left">
Low: <input name="PriceLow" maxlength="7" format="N6N" />


</p>

</card>

<card id="GetPriceHigh">

<do type="accept"> <go href="#RealEstatePrice" /> </do>

<p align="left">

High: <input name="PriceHigh" maxlength="7" format="N6N" />

</p>

</card>

<card id="GetRealEstateResults">

<onevent type="onenterforward">

<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value= "$(PriceLow)&"/> <postfield name="PriceHigh" value= "$(PriceHigh)&"/> </go>

</onevent>

<onevent type="onenterbackward">

<go method="post" href="../waplibcgi/RealEstateWML.pl"> <postfield name="PriceLow" value= "$(PriceLow)&"/> <postfield name="PriceHigh" value= "$(PriceHigh)&"/> </go>

</onevent>

</card>

</wml>

Первые два элемента WML-страницы сообщают WAP-браузерам версию WAP-

спецификации, которую поддерживает приложение. В данном случае WML-

страница совместима с XML 1.0 и описанием типа документа (DTD) версии 1.1,

разработанным ассоциацией WAP Forum. Любая WML-страница, размещаемая

после информации о версии, начинается с тега . В конце каждой WML-

страницы должен находиться соответствующий тег
, который завершает

элементы WML-страницы. Теги и , располагающиеся после тега

, позволяют указывать данные о WML-странице, включая метаданные и информацию, управляющую доступом.

Элемент позволяет определять для WML-страницы метаинформацию. Внашем случае параметр http-equiv=Cache-Control сообщает WAP-браузеру, чтоданная часть метаинформации относится к системе кэширования памяти.


Аналогично, параметр content=max-age= 0 сообщает браузеру, что максимальное время, в течение которого должно выполняться кэширование WML-страницы, равнонулю секунд; то есть, браузер должен не запоминать, а повторно загружать данные с сервера каждый раз, когда поступает запрос. Для данной книги нулевоезначение было выбрано, чтобы помочь читателю в разработке программы. Привыборе нулевого значения каждый раз, когда происходит изменение, оно передается на телефон. В реально эксплуатируемом приложении статическое меню,подобное рассматриваемому здесь, по-видимому, должно использовать интервалхранения, установленный по умолчанию, равным 30 дням. Наконец, параметрforua="true" определяет, что данное значение Cache-Control предназначенодля телефона и не должно удаляться каким-либо промежуточным агентом.

Приложение вначале использует элемент , расположенный внутри карты GetPriceHigh, используется для выводаприглашения пользователю на форматированный ввод.

После того как пользователь введет необходимую информацию и выберет кнопкупоиска (Find), приложение запускает Peri-сценарий RealEstateWML.pl, который, всвою очередь, находит информацию о домах, чьи цены лежат в указанном пользователем ценовом диапазоне.

Рассмотрение приложения RealEstate.hdml

Рассмотрение приложения RealEstate.hdml

Как и приложение на WML, RealEstate.hdml предоставляет пользователю возможность поиска домов, цена которых попадает в указанный ценовой диапазон, и длявыполнения большей части обработки данных использует Peri-сценарий. Приложение RealEstate.hdml реализуется с помощью следующего программного кода наHDML:
<?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" forua="true"/>
</head>
<card id="House">
<do type="accept" label="Back"> <prev/> </do>
<p align="left" mode="nowrap">
MLS #:LV77711<br/> $$249,995<br/> Las Vegas<br/> 4 BR / 2 Ba<br/> 4100 SF<br/> <a href="#MoreInfo" title="Info">More Info</a> </p>
</card>
<card id="MoreInfo">
<do type="accept" label="Back"> <prev /> </do>
<p align="left" mode="nowrap">
Lot Size: 400X400<br/> Year Built: 1998<br/> Fireplace: Yes<br/> Patio: Yes<br/> Pool: Yes<br/> Spa: Yes
</p>
</card>
</wml>
Первый элемент в файле сообщает браузеру (или другим программистам) информацию о версии спецификации HDML, поддерживаемой приложением. Крометого, параметр Markable=True определяет, что браузер может устанавливать наHDML-странице закладку, а параметр TTL=0 предписывает браузеру не выполнятькэширование HDML-страницы. Работа приложения начинается с использованияэлемента , который позволяет, если это требуется пользователю, вводить минимальную или максимальную допустимую цену. Основываясь на сделанном пользователем выборе, приложение переходит на именованный элемент, который выводит на экран приглашение пользователю на ввод соответствующих данных. После того как пользователь введет требуемую информацию,приложение переходит на элемент GetRealEstateResults, который, в свою очередь, запускает Peri-сценарий RealEstateHDML.pl, чтобы найти все дома, удовлетворяющие условиям поиска.

Рассмотрение Реrl-сценария RealEstateWML.pl

Рассмотрение Реrl-сценария RealEstateWML.pl

После указания пользователем верхней и нижней границы цен в приложенииRealEstate, программа запускает Peri-сценарий для поиска домов, цены которыхпопадают в указанный диапазон. Чтобы выполнить данную обработку, Peri-сценарию уже заранее "известна" информация о некотором ограниченном числедомов (в реальном приложении сценарий получал бы необходимую информациюиз базы данных). Чтобы сравнить стоимость известных ему домов с ценовымдиапазоном, сценарий использует серию ветвлений if-else. Если цена на домпопадает в диапазон, сценарий добавляет дом в опции меню.
Perl-сценарий RealEstateWML.pl реализуется с помощью следующего программного кода:
#!/usr/bin/perl
require 'DeckUtils.pl';
%cgiVars = &AppUtils::ParseCGIVars();
$PriceLow = $cgiVars{"PriceLow"}; $PriceHigh = $cgiVars{"PriceHigh"};
$Price1 = 99500; $Price2 = 149995; $Price3 = 249995; $Price4 = 500000; $Price5 = 1500000;
if (($PriceLow <= 0) ($PriceHigh <= 0) ($PriceLow > $PriceHigh))
{ $Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>
</head>
<card id=\"Error\">
<do type=\"accept\" label=\"Back\"> <go href=\"../RealEstate/RealEstate.wml\" /> </do>
<p align=\"left\" mode=\"wrap\">
Error in price range. Please enter a minimum price and a maximum price.
</p>
</card>
</wml>";
}
else
{
$Option = "";
if (($Price1 >= $PriceLow) && ($Price1 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/GV01234.wml \">GV01234 \$\$99,500</option>"; }


if (($Price2 >= $PriceLow) && ($Price2 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/LV01234.wml \">LV01234 \$\$149,995</option>"; }

if (($Price3 >= $PriceLow) && ($Price3 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate/LV77711.wml \">LV77711 \$\$249,995</option>"; }

if (($Price4 >= $PriceLow) && ($Price4 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate /BC01234.wml\">BC01234 \$\$500,000</option>"; }

if (($Price5 >= $PriceLow) && ($Price5 <= $PriceHigh)) { $Option = $Option . "<option onpick=\"../RealEstate /LV11711.wml\">LV11711 \$\$1,500,000</option>"; }

if ($Option eq "")

{ $Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>

</head>

<card id=\"Error\">

<do type=\"accept\" label=\"Back\"> <go href=\"../RealEstate /RealEstate.wml\" /> </do>

<p align=\"left\" mode=\"wrap\">

No houses match the price range.

</p>

</card>

</wml>"; }

else

{ $Deck = "Content-type: text/vnd.wap.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\" forua=\"true\"/>


</head>

<card id=\"Pick\">

<do type=\"accept\" label=\"View\"> <noop /> </do>

<do type=\"options\" label=\"Back\"> <go href=\"../RealEstate /RealEstate.wml\" /> </do>

<p align=\"left\" mode=\"nowrap\">

Pick a house<br/> ...MLS#....Price..

<select> " . $Option . " </select>

</p>

</card>

</wml>"; }

}

print $Deck;

Выполнение сценария начинается с анализа параметров, передаваемых ему WML-страницей Real Estate.wml. Далее, сценарий присваивает переменным, начиная с$Pricel до $Price5, значения в долларовом выражении. Пять переменныхсоответствуют ценам на пять домов, известных сценарию. Затем сценарийиспользует оператор if, чтобы определить введены пользователем минимальнаяи максимальная цены или нет; если это не сделано, сценарий выводит на экрансообщение об ошибке.

Если же пользователь указал ценовой диапазон, программа сравнивает цену каждого из пяти домов с максимальной и минимальной допустимой ценой. Если ценана дом попадает в указанный диапазон, сценарий добавляет информацию о доме(такую, как списочный номер, цена и соответствующий WML-файл) в переменную$0ption. Далее, когда сценарий обработает данные всех пяти домов, будет создансписок домов с желаемой ценой путем размещения переменной $Option внутриэлемента , предоставляющий пользователю возможность указывать пункт данных, который необходимо обновить. Внутри элемента . Когда пользователь выбирает какое-то конкретное приложение, элемент select (Выбор) предписывает браузеру загрузить страницу приложения из соответствующего каталога.

Рассмотрение приложения waplib.com

Рассмотрение приложения waplib.com

При запуске приложения waplib.com выполняется Peri-сценарий index.cgi, чтобы установить тип браузера пользователя. Тип браузера определяется путем анализазначения параметра НТТР_АССЕРТ, получаемого от браузера, запрашивающего сервис. Сценарий index.cgi реализуется с помощью следующего программного кода:
#!/usr/bin/perl
$WAPwml = ""; $WAPhdml = "";
$accept = $ENV{"HTTP_ACCEPT"};
if ($accept =~ /wml/) { $WAPwml = "wml"; }
if ($accept =~ /hdml/) { $WAPhdml = "hdml"; }
if (($WAPwml eq "") && ($WAPhdml eq "")) { print "Location: http://www.waplib.com/WebStart.html\n\n"; }
elsif (($WAPwml eq "wml") && ($WAPhdml eq "")) { print "Location: http://www.waplib.com/Demos.wml\n\n"; }
elsif (($WAPwml eq "") && ($WAPhdml eq "hdml")) { print "Location: http://www.waplib.com/Demos.hdml\n\n"; }
else { print "Location: http://www.waplib.com/Both.hdml\n\n"; }
Приложение использует функцию $ENV для выборки значения переменнойНТТР_АССЕРТ. Затем программа выполняет проверку, чтобы определить, включает лизначение переменной буквы wml. При положительном результате (когда буквы wmlприсутствуют), программный код присваивает значение wml переменной $WAPwml,которую позже он может проверить с помощью конструкции условного перехода if.Далее выполняется аналогичная проверка в отношении букв hdml. Если ни переменной $WAPwml, ни переменной $WAPhdml не присвоены значения, то это означает, чтобраузер не поддерживает ни WML, ни HDML, вследствие этого приложение запускаетHTML-файл WebStarthtml, отображающий сообщение о скором выходе книги "WAP вдействии. Доступ к Интернет-сайтам через сотовый телефон".
Заметьте, что сценарий запускает WML-, HDML- или HTML-файлы просто путем печати слова Location (Адрес), за которым следует требуемый URL. Когда браузервстречает URL в таком формате, он совершает ветвление, переходя на соответствующий адрес.
В реальном приложении ваш HTML-сайт, вероятно, будет выполнять обработкуданных, связанную или не связанную с WML- и HDML-сайтами. HTML-файлWebStart.html содержит следующий программный код:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html> <head> <title>WAPLIB</title> </head>
<body> <div align="center"><h1>Wireless Applications Programmer's Library</h1></div><br> <div align="center"><h2>Coming soon</h2></div>
</body> </html>

Приложение

Арифметические операции

Арифметические операции


В языке WMLScript реализованы следующие базовые бинарные арифметические
операции:




































































Оператор


Операция




+


сложение чисел или объединение символьных строк












-


вычитание




*


умножение




/


деление




div


целочисленное деление







Кроме того, язык WMLScript поддерживает следующий набор более сложных бинарных арифметических операций:




































































Оператор


Операция




%


остаток от деления (знак результата совпадает со знаком
делимого)




"


поразрядное смещение влево




"


поразрядное смещение вправо




>>>


поразрядное смещение вправо с заполнением нулями




&


поразрядная операция "И" (AND)




1


поразрядная операция "ИЛИ" (OR)




/\


поразрядная операция "исключающее ИЛИ" (XOR)








Библиотека Console

Библиотека Console


Библиотека Console содержит набор функций, которые могут быть полезными
при отладке программ.

Print
Функция: Console.print(value);

Описание: Преобразует заданное значение в строку и выводит ее в информационное окно инструментального программного пакета (SDK) Phone.
Аргумент: value = Любое значение

Пример: Следующий сценарий использует функцию

Console.print(), чтобы в отладочных целях

вывести три имени в одну строку в информаци-

онном окне инструментального программного

пакета Phone:
extern function PrintTestO

{
var Namel = "Matt";

var Name2 = "Krissy";
var Name3 = "Tommy";

Console.print (Namel);
Console.print (Name2);
Console.print (Name3);
}

Println

Функция: Console.println(value);

Описание: Преобразует заданное значение в строку, выводит ее в информационное окно SDK Phone и перемещает курсор на следующую строку.
Аргумент: value = Любое значение

Пример: Следующий сценарий использует функцию

Console.println(), чтобы в отладочных целях
вывести три имени на три разные строки в ин формациошюм окне инструментального пакета

Phone:

extern function PrintLnTest()

var Namel = "Matt";

var Name2 = "Krissy";

var NameS = "Tommy";

Console.println (Namel);

Console.println (Name2);

Console.println (NameS);

Библиотека Dialogs

Библиотека Dialogs


Библиотека Dialogs предоставляет набор функций пользовательского интерфейса.


alert

Функция: Dialogs.alert(message);

Описание: Отображает заданное сообщение, ожидает под-
. тверждения со стороны пользователя и возвра-
щает пустую строку.

Аргумент: message = Строка

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

Dialogs. alert () для вывода на экран сообщения:

extern function AlertTestO
{

var ResultString = "Dialogs .alert () " + "\r\r"
"This is an alert!

Dialogs .alert (ResultString) ; .
}

confirm

Функция: Dialogs.confirm(message, OKPrompt, Cancel-
Prompt) ;

Описание: Отображает заданное сообщение и предоставляет пользователю возможность выбора из двух

ответов. Возвращает логическое значение true,

если выбран ответ ок и false, если выбран ответ Cancel.

Аргументы: message = Строка

, OKPrompt = Строка

CancelPrompt = Строка

Возвращаемое значение: Строка

Пример: Следующий сценарий использует функцию

Dialogs. confirm () для отображения приглашения пользователю на взаимодействие с приложением, причем приглашение включает экранные кнопки Yes и No:

extern function ConfirmTest()
{

var Message = "Dialogs.confirm()" + "\r\r" + "Are you sure?";
var OK = "Yes";
var Cancel = "No";

Dialogs.confirm(Massage, OK, Cancel);

}

prompt

Функция: Dialogs.prompt(message, default);

Описание: Отображает указываемое сообщение message в

качестве приглашения пользователю на взаимодействие с приложением и возвращает вводимые пользователем данные. Используемое по
умолчанию значение default определяет начальное содержимое переменной, которой присваиваются вводимые пользователем данные.

Аргументы: message = Строка

default = Строка
Возвращаемое значение: Строка

Пример: Следующий сценарий использует функцию

Dialogs. prompt () для вывода приглашения

пользователю на ввод номера телефона. По

умолчанию пользователю для редактирования
предлагается значение 555-1212:

extern function PromptTestO

var Message = "Dialogs.prompt()" + "\r\r" + "Phone Number:";
var PhoneNo = "555-1212";

Dialogs.prompt(Message, PhoneNo);

Библиотека Float

Библиотека Float


Библиотека Float содержит набор функций для работы с числами в формате с
плавающей запятой. Наличие данных функций носит необязательный характер.
Если устройство не поддерживает операции над числами с плавающей запятой,
все функции данной библиотеки будут возвращать значение invalid.

Ceil

Функция: Float, ceil (value);

Описание: Возвращает наименьшее целое число, которое

превышает входное значение аргумента или
равно ему. Если входное значение аргумента -
целое число, функция возвращает это число.

Аргумент: value = Число

Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию
Float, ceil () для нахождения наименьших целых чисел, одно из которых не меньше положи тельного числа с плавающей запятой, а другое -
не меньше отрицательного числа с плавающей
запятой:

extern function CeilTestO
{

var Argumentl = 10.5;
var Resultl = Float.ceil(Argumentl);

var Argument2 = -5.5;
var Result2 = Float.ceil(Argument2);

var ResultString = "Float.ceil()" + "\r\r" +

"ceil(10.5) = " + Resultl + "\r" +
"ceil(-5.5) = " + Result2;


Dialogs.alert(ResultString);

}

floor

Функция: Float, floor (value);

Описание: Возвращает наибольшее целое число, которое

меньше входного значения аргумента или равно
ему. Если входное значение аргумента - целое
число, функция возвращает это число.

Аргумент: value = Число
Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию

Float.floor() трижды: для нахождения наибольших целых чисел, одно из которых должно
быть не больше положительного числа с плавающей запятой, другое - не больше отрицательного числа с плавающей запятой и третье -
не больше целого числа:

extern function FloorTestO

{ .
var Argumentl = 10.5;

, var Resultl = Float.floor(Argumentl);

var Argument2 = -5.5;

var Result2 = Float, floor (Argument2) ;

var Arguments = 300;


var Results = Float.floor(Arguments);

var ResultString = "Float.floor()" + "\r\r" +
"floor(10.5) = " + Resultl + "\r" +
"floor(-5.5) = " + Result2 + "\r" +
"floor(SOO) = " + Results;

Dialogs.alert(ResultString);
}

int

Функция: Float, int (value);

Описание: Возвращает целую часть входного значения аргумента.

Аргумент: value = Число

Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию

Float. int () для извлечения целой части как у
положительных, так и у отрицательных чисел с
плавающей запятой:

extern function IntTestQ
{

var Argumentl = 10.5;

var Resultl = Float.int(Argumentl);

var Argument2 =-5.5;
var Result2 = Float, int (Arguments) ;

var ResultString = "Float.int()" + "\r\r" +

"int(10.5) = " + Resultl + "\r" +
"int(-5.5) = " + Result2;

Dialogs.alert(ResultString) ;

}

maxFloat

Функция: Float. maxFloat ();

Описание: Возвращает наибольшее число с плавающей запятой, поддерживаемое интерпретатором.

Возвращаемое значение: Число с плавающей запятой

Пример: Следующий сценарий использует функцию

Float. maxFloat () для определения наибольшего числа с плавающей запятой, которое поддерживает интерпретатор:

extern function maxFloatTest ()

{

var Result = Float. maxFloat О;

var ResultString = "Float.maxFloat() " + "\zr\r" + Result;
Dialogs.alert(ResultString);

}

minFloat

Функция: Float. minFloat ();

Описание: Возвращает наименьшее число с плавающей запятой, поддерживаемое интерпретатором.

Возвращаемое значение: Число с плавающей запятой

Пример: Следующий сценарий использует функцию

Float.minFloat () для определения наименьшего числа с плавающей запятой, работу с которым поддерживает интерпретатор:

extern function minFloatTestO

{

var Result = Float.minFloat();

var ResultString = "Float.minFloat()" + "\r\r" + Result;

Dialogs.alert(ResultString);

pow

Функция: Float, pow (valuel, value2);

Описание: Возвращает результат возведения первого аргумента (valuel) в степень, равную второму аргументу (value2). Если значение первого аргумента (valuel) является отрицательным числом, то
значение второго аргумента (valua2) должно

быть целочисленным.

Аргументы: valuel = Число

value2 = Число

Возвращаемое значение: Число с плавающей запятой или значение

invalid

Пример: Следующий сценарий использует функцию

Float. pow () для вычисления результата возведения 3 в степень 2 и корня квадратного из 16:

extern function PowTestO
<
var Argumentl = 3;
var Arguments = 2;
var Resultl = Float.pow(Argumentl, Argument2);

var Arguments = 16; var Argument4 = .5;

var Result2 = Float.pow(Arguments, Argument4);

var ResultString = "Float.pow()" + "\r\r" +
"pow(3, 2) = " + Resultl + "\r" +
"pow(16, .5) = " + Result2;

Dialogs.alert(ResultString);

}

round
Функция: Float.round(value);

Описание: Возвращает целое число, ближайшее к входному
значению. Если два целых числа одинаково
близки к входному значению, функция возвращает большее из этих чисел.

Аргумент: value = Число
Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию

Float.roundO для округления чисел 5.4, 5.5 и

5.6 до ближайшего целого числа:

extern function RoundTest()

{

var Argument! = 5.4;

var Resultl = Float.round(Argumentl);

var Argument2 = 5.5;

var Result2 = Float.round(Argument2);

var Arguments = 5.6;
var Results = Float.round(Arguments);

var ResultString = "Float.round()" + "\r\r" +

"round(5.4) = " + Resultl + "\r"

"round(5.5) = " + Result2 + "\r" +

"round(5.6) = " + Results,-

Dialogs.alert(ResultString);

}

sqrt
Функция: Float, sqrt (value);

Описание: Возвращает корень квадратный из входного

значения. Если входное значение отрицательно,

функция возвращает значение invalid.

Аргумент: value = Число

Возвращаемое значение: Число с плавающей запятой или значение

invalid

Пример: Следующий сценарий использует функцию
Float.sqrt() для вычисления корней квадратных из 2 и-9:

extern function SqrtTest() ,

{

var Argumentl = 2;

var Resultl = Float, sqrt (Argumentl) ; vis.

var Argument2 = -9;
var Result2 = Float. sqrt (Argument2);

var ResultString = "Float.sqrt()" + "\r\r" +

"sqrt(2) = " + String.toString(Resultl) +
"sqrt(-9) = " + String.toString(Result2);

Dialogs.alert(ResultString);

}

Библиотека Lang

Библиотека Lang


Библиотека Lang содержит набор функций, предназначенных для работы с элементами языка WMLscript.

Функция: Lang.abort(errorMessage);

Описание: Прерывает работу интерпретатора WMLScript и

возвращает управление WML-странице.

Аргумент: errorMessage = Строка
Возвращаемое значение: Нет

Пример: Следующий сценарий демонстрирует использо-
вание функции Lang.abort() для прекращения
работы сценария:

extern function AbortTestO


{

var Argument = 0;
BadFun(Argument);

Dialogs.alert("This will never display");

function BadFun (Argument)

Lang.abort("Error:");

Dialogs, alert ("Neither will this,

}

Функция: ; bang, abs (number);

Описание: К, Возвращает абсолютное значение числа. Если

число имеет тип integer (целое число), возвращается целочисленное значение. Если число

имеет тип floating-point (число с плавающей
запятой), возвращается число с плавающей запятой.

Аргумент: number = Число

Возвращаемое значение: Число или значение invalid

Пример: Следующий сценарий использует функцию

Lang.abs() дважды: первый раз, чтобы возвратить абсолютное значение отрицательного целого числа, второй раз, чтобы возвратить абсо лютное значение отрицательного числа с плавающей запятой:

extern function AbsTestO
<

var Argumentl = -5;

var Resultl = Lang.abs(Argumentl);

var Arguments = -7 . ;

var Result2 = bang.abs(Arguments); ,

var ResultString = "Lang.abs()" + "\r\r" +

"abs(-5) = " + Resultl + "\r" +

"abs(-7.) = " + Result2; :,n

Dialogs. alert (ResultString) ; ;- >

}

characterSet

Функция: Lang. characterSet О;

Описание: Возвращает целочисленное значение, которое

указывает на набор символов, поддерживаемых
интерпретатором.

Возвращаемое значение: Целое число

Пример: Следующий сценарий использует функцию

Lang.characterSet() для определения набора
символов, поддерживаемых интерпретатором.

extern function CharSetTest() м

{
var Result = Lang.characterSet();

var ResultString = "Lang.characterSet () " + "\r\r" + Result/-
Dialogs .alert(ResultString);

>

exit

Функция: Lang. exit (value);

Описание: Останавливает выполнение WMLScript-сценария

и возвращает управление WML-странице.

Аргумент: value = Любое значение
Возвращаемое значение: Нет

Пример: Следующий сценарий демонстрирует использование функции Lang.exit() для прекращения
выполнения сценария.

extern function ExitTestO
{

var Argument = 0;
BadFun(Argument);
Dialogs.alert("This will never display");

function BadFun (Argument) :

Lang.exit ("Error:");
Dialogs.alert("Neither will this");

}

Функция: Lang.floatO ;

Описание: Возвращает логическое значение true, если

числа с плавающей запятой поддерживаются

интерпретатором и false, если числа с плавающей запятой не поддерживаются интерпретатором

Возвращаемое значение: Логическое значение

Пример: Следующий сценарий использует функцию

Lang. float (), чтобы определить поддерживаются интерпретатором числа с плавающей запя той или нет:

extern function FloatTestO

var Result = Lang.floatO ;
var ResultString = "Lang.floatO" + "\r\r" + Result;

Dialogs.alert(ResultString);
}

isFloat

Функция: Lang.isFloat(value);

Описание: Возвращает значение true, если аргумент функ-

ции может быть конвертирован в число с плавающей запятой и возвращает значение false,
если аргумент функции не может быть конвертирован в число с плавающей запятой. Если система не поддерживает операции над числами с

плавающей запятой или аргумент имеет недопустимое значение, функция возвращает значение invalid.

Аргумент: value = Любое значение
Возвращаемое значение: Логическое значение или значение invalid

Пример: Следующий сценарий использует функцию

bang. isFloat (), чтобы определить, могут ли

значения "5.0", "7" и "String" быть конвертированы в числа с плавающей запятой:

extern function isFloatTest() :
{

var Argumentl = "5.0"; "*'"'

var Resultl = Lang.isFloat(Argumentl) ;

var Argument2 = "7";

var Result2 = Lang.isFloat(Argument2);

var Arguments = "String";

var Results = Lang.isFloat(Arguments);

var ResultString = "Lang.isFloat ()" + "\r\r" 4-

"isFloat(5.0) = " + Resultl + "\r" +
"isFloat(7) = " + Result2 + "\r" +
"isFloat (String) = " + Results,-

Dialogs.alert(ResultString);

}

Функция: Lang.islnt (value);

Описание: Возвращает логическое значение true, если

аргумент функции может быть конвертирован в

целое число и возвращает логическое значение

false, если аргумент функции не может быть

конвертирован в целое число. Если аргумент

имеет недопустимое значение, возвращается

значение invalid.

Аргумент: value = Любое значение

Возвращаемое значение: Логическое значение или invalid

Пример: Следующий сценарий использует функцию
Lang.isIntO, чтобы определить могут ли значения "5.0", "7" и "String" быть конвертированы в целые числа:

extern function is!ntTest() ;;

{
var Argumentl = "5.0";
var Resultl = Lang.islnt(Argumenfel);

var Argument2 = "7";
var Result2 = Lang. islnt (Argument2) ;

var Arguments = "String";
var Results = Lang.islnt(Arguments);

var ResultString = "Lang.isIntO" + "\r\r" +

"islnt(5.0) = " + Resultl + "\r" +
"islnt(7) = " + Result2 + "\r" +

"islnt (String) = " + Results;

Dialogs.alert(ResultString);
}

max

Функция: Lang.max(valuel, value2);

Описание: Возвращает большее из двух значений.

Возвращаемое функцией значение и его тип
совпадают со значением и типом возвращаемого
аргумента. Если значения равны, возвращается
первый аргумент.

Аргументы: valuel = Число

value2 = Число
Возвращаемое значение: Число или значение invalid

Пример: Следующий сценарий использует функцию

Lang.maxO трижды: для определения большего

положительных чисел, двух отрицательных чисел, а также символьной строки и числа:

extern function MaxTestO

var Argumentl = 5.0;

var Argument2 = 500;

var Resultl = Lang.max(Argumentl, Argument2);

var Arguments = -7;

var Argument4 = -10.0;

var Result2 = Lang.max(Arguments, Argument4);

var Arguments = "String";
var Arguments = 0.0;
var Results = Lang.max(Arguments, Arguments);

var ResultString = "Lang.maxO" + "\r\r" +

"max(5.0, 500) = " +

String.toString(Resultl) + "\r" +
"max(-7, -10.0) = " +

String.toString(Result2) + "\r" +
"max(String, 0.0) ="+ I
String.toString(Results);

Dialogs.alert(ResultString);

maxlnt

Функция: Lang.maxlnt();

Описание: Возвращает значение максимального целого

числа, поддерживаемого интерпретатором.

Возвращаемое значение: Целое число

Пример: Следующий сценарий использует функцию

Lang.maxlnt() для определения максимального
целого числа, поддерживаемого интерпретато-

ром:

extern function maxIntTestO

{
var Result = Lang.maxlnt();

var ResultString = "Lang.maxlnt()" + "\r\r" + Result;
Dialogs.alert(ResultString) ;

mm

Функция: Lang.min(valuel, value2);

Описание: Возвращает меньшее из двух значений.

Возвращаемое функцией значение и его тип

совпадают со значением и типом возвращаемого

аргумента. Если значения равны, возвращается
первый аргумент.

Аргументы: valuel = Число

value2= Число
Возвращаемое значение: Число или значение invalid

Пример: Следующий сценарий использует функцию

Lang.minQ трижды: для определения меньшего
из двух положительных чисел, двух отрицатель-
ных чисел, а также символьной строки и числа:

extern function MinTestO

var Argumentl = 5.0;

var Argument2 = 500;

var Resultl = Lang.min(Argumentl, Argument2);

var Arguments = -7;

var Argument4 = -10.0;

var Result2 = Lang.min(Arguments, Argument-!) ;

var Arguments = "String";

var Arguments =0.0;

var Result3 = Lang.min(Arguments, Arguments);

var ResultString = "Lang.minO" + "\r\r" +
"min(5.0, 500) = " +

String.toString(Resultl) + "\r" +
"min(-7, -10.0) = " +

String.toString(Result2) + "\r" +
"min(String, 0.0) = " +

String.toString(Results);

Dialogs . alert (ResultString) ;

>

minlnt

Функция: 'Lang. minlnt ();

Описание: Возвращает значение минимального целого

числа, поддерживаемого интерпретатором.

Возвращаемое значение: Целое число

Пример: Следующий сценарий использует функцию

bang. minlnt () для определения минимального

целого числа, поддерживаемого интерпретато-
ром:

extern function minlntTestO

var Result = Lang.minlnt();

var ResultString = "Lang.minlnt()" + "\r\r" + Result;
Dialogs.alert(ResultString) ;

parserloat

Функция: Lang.parseFloat (stringValue);

Описание: Возвращает значение в формате числа с плавающей запятой, которое определяется входной
символьной строкой. Если при анализе строки
выдается ошибка, функция возвращает значение

invalid. Анализ прекращается при встрече первого символа, который не является частью кор-

ректного числа с плавающей запятой.

Аргумент: stringValue = Символьная строка

Возвращаемое значение: Число с плавающей запятой или значение

invalid

Пример: Следующий сценарий использует функцию

Lang.parseFloat () для преобразования

СИМВОЛЬНЫХ строк "5.0", "15 sq. in." И "А = 5"
в числа с плавающей запятой:
extern function ParseFloatTest()
var Argumentl = "5.0";

var Resultl = Lang.parseFloat(Argumentl);

var Argument2 = "15 sq. in.";

var Resuit2 = Lang.parseFloat(Argument2);

var Arguments = "A = 5"; t ч
var Results = Lang.parseFloat(Arguments);

var ResultString = "Lang.parseFloat()" + "\r\r" +

"parseFloat(5.0) = " +
: "-'''!""!' String. toString(Resultl) + "\r" +

"parseFloat(15 sq. in.) = " +

'- ,''*''" '< -' - String. toString (Result2) + "\r" +
"parseFloat(A = 5) = " +
String.toString(Results);

Dialogs, alert (ResultString) ;

}

parselnt

Функция: Lang.parselnt(stringValue); Описание: Возвращает целочисленное значение, которое

определяется входной символьной строкой. Еc
ли при анализе строки выдается ошибка, функвозвращает значение invalid. Анализ прекращается при встрече первого символа, который не является начальным знаком "+" или
или десятичной цифрой.

Аргумент: stringValue = Символьная строка
Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию
bang.parselnt() для преобразования символьных

строк "5. О", "15 sq. in." и "А = 5" в целые числа:

extern function ParselntTest()

{
var Argumentl = "5";
var Resultl = Lang.parselnt (Argumentl) ;

var Arg\iment2 = "15 sq. in."; ,
var Result2 = Lang.parselnt(Argument2);

var Arguments = "A = 5"; t

var Results = Lang.parselnt(Arguments);

var ResultString = "Lang.parselnt()" + "\r\r" +

"parselnt(5) = " +

String. toString (Resultl) + "\r" +
"parselnt(15 sq. in.) = " +
String.toString(Result2) + "\r" +
"parselnt (A = 5) = " +

String.toString(Results);

Dialogs .alert (ResultString)

random

Функция: bang, random (value);

Описание: Возвращает псевдослучайное целое число, коорсе больше или равно нулю и при этом меньше или равно входному значению аргумента

функции. Если входное значение равно нулю,

функция возвращает нуль. Если входное значение отрицательно или не является числом

(строка или недопустимое значение), то функ ция возвращает значение invalid.

Аргумент: value = Целое число


Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию

bang. random () дважды: для выдачи одного

псевдослучайного числа в диапазоне между 0 и

10, а другого псевдослучайного числа - между О

и-10:

extern function RandomTestO

{

var Argumentl =10;

var Resultl = Lang.random(Argumentl);

var Argument2 = -10;

var Result2 = Lang. random (Argument2);

var ResultString = "Lang.randomO" + "\r\r" +

"random(10) = " + String.toString(Resultl) +

"random(-lO) = " + String.toString(Result2);

Dialogs.alert(Resultstring);
}

seed

Функция: bang, seed (value);

Описание: Инициализирует процесс генерации псевдослу чайных чисел и возвращает пустую строку. Если

входное значение больше или равно нулю, то оно

используется в качестве инициализирующего

значения; в противном случае используется системно-зависимое значение. Если входное значение аргумента функции не является числом,

функция возвращает значение invalid.

Аргумент: value = Целое число
Возвращаемое значение: Символьная строка или значение invalid

Пример: Следующий сценарий использует функцию

Lang. seed () для инициализации генератора

псевдослучайных чисел:

extern function SeedTestO

{

var Argumentl = 10;

var Resultl = Lang. seed (Argumentl);

var Argument2 = 5;
var Result2 = Lang.random(Argument2) ;

var ResultString = "Lang.seed()" + "\r\r" +

л "seed(10) = " + String.toString(Resultl) ;

Dialogs.alert(ResultString); ;

}

Библиотека String

Библиотека String


Библиотека String содержит набор функций для работы с символьными строками.
Строка представляет собой массив символов. Позиция каждого символа в строке
задается его индексом. Индекс первого символа в строке равен нулю. Строка может также рассматриваться как массив элементов, разделяемых с помощью разделительного символа. Позиция каждого элемента в строке задается его индексом. Индекс первого элемента в строке равен нулю.

char At

Функция: String.charAt(string, offset);

Описание: Возвращает строку, состоящую из одного знака,

который совпадает с символом входной строки

и, в позиции, указываемой аргументом функции.

Первый символ во входной строке находится по
нулевому адресу.

Аргументы: string = Символьная строка

off set = Число
Возвращаемое значение: Символьная строка или значение invalid

Пример: Следующий сценарий использует функцию

String, char At () для извлечения из строки
"Phil" второго и третьего символов:

extern function charAtTestO

{
var Argumentl = "Phil";
var Argument2 =1;
var Resultl = String.charAt(Argumentl, Argument2);

var Arguments = 2;

var Result2 = String.charAt(Argumentl, Arguments);

var ResultString = "String.charAt()" + "\r\r" +

,, "String, char At (Phil, 2) = " 4- ; в

Resultl + "\r" +
"String.charAt(Phil, 3) = " + Result2;

Dialogs, alert (Resul tString) ;
}

compare

Функция: String, compare (stringl, string2);

Описание: Сравнивает две строки и возвращает значение

"-1", если первая строка (stringl) меньше, чем
вторая строка (string2); возвращает значение
"О", если строки одинаковы; и возвращает значение "+1", если первая строка (stringl) больше, чем вторая строка (string2).

Аргументы: stringl = Строка

string2 = Строка
Возвращаемое значение: Целое число или значение invalid

Пример: Следующий сценарий использует функцию

String, compare () для сравнения строк "а" и "А":

extern function CompareTest()

{
var Argumentl = "a";
var Argument2 = "A";

var Resultl = String.compare(Argumentl, Argument2);
var Result2 = String.compare(Argument2, Argumentl);

var ResultString = "String.compare()" + "\r\r" +

"String.compare(a, A) = " + Resultl + "\r" +

"String.compare(A, a) = " + Result2;

Dialogs.alert{ResultString);
}

elementAt

Функция: String.elementAt(string, index, separator);

Описание: Сканирует строку string с элементами, разделяемыми символом-разделителем separator и
возвращает элемент, расположенный в позиции,

определяемой аргументом index. Eсли значение
index меньше нуля, функция возвращает пер-

вый элемент. Если значение index больше количества элементов, функция возвращает послед-
ний элемент. Если входная строка пустая, возвращается пустая строка. Если символ-
разделитель является пустой строкой, функция
возвращает значение invalid.

Аргументы: string = Строка

index = Число

separator = Строка (используется только пер-
вый символ строки)

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
String.elementAt() для извлечения из списка
третьего имени:

extern function elementAtTest ()

{

var Argument = "Matt Tommy Krissy Rosey" ;
var Index=2;
var Separator = " ";
var Result = String.elementAt(Argument, Index, Separator);

var ResultString = "String.elementAt()" + "\r\r" +
"Third element is " + Result;

Dialogs.alert(ResultString);

}

корректным элементом, поэтому в любой строке

будет, по крайней мере, один элемент. Если сим-

вол-разделитель является пустой строкой, функция возвращает значение invalid.

Аргументы: string = Строка

separator = Строка (используется только первый символ строки)

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

String.elements () для подсчета количества


имен в списке:

extern function elementsTest ()

{
var Argument = "Matt Tommy Krissy Rosey";

var Separator = " ";
var Result = String.elements(Argument, Separator);

var ResultString = "String.elements()" + "\r\r" +'

" The number of elements is " + Result;

Dialogs.alert(ResultString);

}

find

Функция: String.find(string, substring);

Описание: Возвращает индекс (отсчитываемый от нуля)

первого символа, с которого во входной строке

(string) начинается подстрока, совпадающая с

указываемой подстрокой (substring). Функция

возвращает "-1", если во входной строке не об-

наружено совпадения с указываемой подстро кой. Две строки совпадают только тогда, когда

они полностью одинаковы, включая регистры

всех символов.

Аргументы: string = Строка

substring = Строка
Возвращаемое значение: Целое число

Пример: Следующий сценарий использует функцию

string.find() для определения в строке

"аЬсАВС123" позиции подстроки "АВ":

extern function FindTestO

<

var Argument = "abcABC123";
var LookFor = "AB";
var Result = String.find(Argument, LookFor);

var ResultString = "String, find ()" + "\r\r" +
"The Index of AB is " + Result;

Dialogs.alert(ResultString) ; .

}

format

Функция: String, format (format, value);

Описание: Преобразует значение аргумента value в символьную строку в соответствии со значением
аргумента format. Аргумент format определяется следующим образом:

[width][.precision]type

Параметр width (Ширина) указывает мини-
мальное число печатаемых символов. Если на
выходе число символов меньше, чем значение,
определяемое параметром width, выходная
строка дополняется слева пробелами так, чтобы
получилось минимальное число символов. По
умолчанию минимальное число символов, опре деляемое параметром width, равно единице.

Интерпретация параметра precision (Точность) зависит от значения параметра type


(Тип). Для типа d ( целые числа) точность определяет минимальное число разрядов в выходной
строке. Если число разрядов в выходной строке
меньше значения, определяемого точностью,
выходная строка дополняется слева нулями. Для
типа f (числа с плавающей запятой) точность
определяет число разрядов в выходной строке
после десятичной точки (во всех случаях до десятичной точки должен существовать хотя бы
один разряд). По умолчанию число разрядов
равно шести. Для типа s (строковые перемен-

ные) точность определяет число символов в вы ходной строке. По умолчанию в выходную стро ку будут выводиться все символы входного значения аргумента value.

Параметр type (Тип) определяет, как будет интерпретироваться результат, возвращаемый
функцией: как целое число (d), как число с плавающей запятой (f) или как строка (s).

Аргументы: format = Строка

value = Любое значение
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

String, format () для вывода значения 10.25 в
виде шестиразрядного числа с плавающей запятой, у которого после десятичной точки нахо-

дится всего один разряд:

extern function FormatTestO

{

var Format = "%6.1f";
var Argument =10.25;
var Result = String.format(Format, Argument);

var ResultString = "String.format()" + "\r\r" +,
"The result is: " + Result;

Dialogs .alert (ResultString) ;

}

insertAt

Функция: String.insertAt(string, element, index,

separator);

Описание: Возвращает строку с новым элементом (и, если
необходимо, с разделителем), вставленным в

исходную строку в позицию, определяемую арументом index. Если значение index меньше

или равно нулю, элемент вставляется в начало
строки. Если значение index больше количества
элементов в строке, элемент вставляется в конец строки. Если разделительный символ представляет собой пустую строку, функция возвра щает значение invalid.

Аргументы: format = Строка

element = Строка

index = ЧИСЛО

separator = Строка (используется только пер-
вый символ)

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
String.insertAt() для вставки в список между
именами Matt и Tommy имени Krissy:

extern function InsertAtTest ()

{
var List = "Matt Tommy";
var tolnsert = "Krissy";
var Index = 1;
var Separator = " ";

var Result = String.insertAt(List, tolnsert, Index, Separator);

var ResultString = "String.insertAt()" + "\r\r" +

" The new string is: " + Result;

Dialogs.alert(ResultString);
}

ISEmpty

Функция: String. isEmpty( string);

Описание: Возвращает логическое значение true, если

строка имеет нулевую длину и значение false,
если длина строки ненулевая.

Аргумент: string = Строка
Возвращаемое значение: Логическое значение

Пример: Следующий сценарий использует функцию

String. isEmpty (), чтобы установить являются
ли строки "Matt" и " " пустыми:

extern function IsEmptyTest()

{
var Argumentl = "Matt";
var Resultl = String.isEmpty(Argumentl);

var Argument2 = "";

var Results = String. isEmpty (Arguments) ;

var ResultString = "String.isEmpty()" + "\r\r" +

"isEmpty (\"Matt\") = " 4- Resultl + "\r",
"isEmpty(\"\") = " + Result2;

Dialogs.alert(ResultString) ;

}

length

Функция: String.length(string);

Описание: Возвращает длину (количество символов) строки.

Аргумент: string = Строка

Возвращаемое значение: Целое число

Пример: Следующий сценарий использует функцию

String, length () для подсчета количества
символов в строке "Champion Matt":

extern function Lengthiest()
{

var Argument = "Champion Matt";

var Result = String.length(Argument);

var ResultString = "String.length()" + "\r\r" +
"length(\"Champion Matt\") = " + Result;

Dialogs.alert(ResultString);
)

removeAt

Функция: String. removeAt (string, index, separator);

Описание: Возвращает новую строку, получаемую из исходной строки путем удаления элемента (и, если
необходимо, разделителя), который находится в
позиции, определяемой значением index. Если
значение index меньше или равно нулю, удаля ется первый элемент. Если значение index
больше, чем количество элементов в строке,
удаляется последний элемент. Если аргумент
string пустой, функция возвращает пустую
строку. Если символ разделителя представляет
собой пустую строку, функция возвращает значение invalid.

Аргументы: string = Строка

index = ЧИСЛО

separator = строка (используется только первый символ)

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
String.removeAt () для удаления из списка имени Krissy:

extern function RemoveAtTest ()
{

var List = "Matt Krissy Tommy";
var Index = 1;
var Separator = " ";

var Result = String.removeAt(List, Index, Separator);

var ResultString = "String.removeAt()" + "\r\r" +
"The new string is: " + Result;

Dialogs . alert (ResultString) ;

}

вода строки, перевода страницы, вертикальной

табуляции) до одного, первого непечатаемого

символа.

Аргумент: string = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

String, squeeze () для удаления между именами
"Matt" и "Tommy" всех лишних пробелов, кроме
одного:

extern function SqueezeTest()

{

var List = "Matt Tommy";
var Result = String.squeeze(List);

var ResultString = "String.squeeze()" + "\r\r" +

"The new string is: " + Result;

Dialogs.alert(ResultString);

}

substring

Функция: String.substring(string, index, length);

Описание: Возвращает новую строку, которая представляет
собой подстроку исходной строки. Новая строка

начинается с символа входной строки string,
расположенного в позиции index, и содержит
количество символов, определяемое аргументом
length.

Аргументы: string = Строка

index = Число


length = ЧИСЛО

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

String.substring() для извлечения из списка
имени "Krissy":

extern function SubStringTest()

{
var List = "Matt Krissy Tommy";
var startChar = 5;
var Length = 6;

var Result = String.substring(List, startChar, Length);

var ResultString = "String.substring()" + "\r\r" +

"The substring is: " + Result/
Dialogs .alert (ResultString) ;

}

extern function ToStringTest()

var Argument! =3.14;
var Resultl = String.toString(Argumentl);

var Argument2 = 1/0;

var Result2 = String. toString(Argument2);

var Arguments = true;

var Results = String.toString(Arguments);

var ResultString = "String.toString()" + "\r\r" +

"toString(3.14) = " + Resultl + "\r" +
"toString(1/0) = " + Result2 + "\r" +
"toString (true) = " + Results,-

Dialogs.alert(ResultString);

}

!l trim

Функция: String.trim(string);

Описание: Возвращает новую строку, получаемую из входной строки string, путем удаления всех непечатаемых символов в начале и в конце исходной

СТРОКИ.

Аргумент: string = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
String.trim() для удаления всех пробелов с
обоих концов строки - аргумента функции:

extern function TrimTestO

{
var Argument = " Matt " ;

var Result = String.trim(Argument);

var ResultString = "String.trim()" + "\r\r" +

"The new string is: " + Result;

Dialogs.alert(ResultString);
}

Библиотека URL

Библиотека URL


Библиотека URL содержит набор функций для работы как с абсолютными, так и с
относительными указателями ресурсов (URL).

В общем случае URL описывается следующей синтаксической конструкцией:
://:/;?#

escapeString

Функция: URL. escapeString (string);

Описание: Возвращает новую строку, получаемую из вход-
ной строки string путем замены всех спецсим-
волов на ESCAPE-последовательности в формате
%хх. Если входная строка содержит символы, не
являющиеся частью набора символов US-ASCII,
функция возвращает значение invalid.

ESCAPE-последовательности заменяются сле-
дующие символы:

Управляющие символы: (шестнадцатеричные

значения ОО-lf и 7f из
набора символов USASCII)

Знак пробела: (шестнадцатеричное

значение 20 из набора
символов US-ASCII)

Зарезервированные
символы: ;/?:@& = + $,

Несмысловые символы: () |\Л[]'

Разделители:

Аргумент: string = Строка

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL.escapeStringO для кодирования строки
"@&#":

extern function EscapeStringTest()

{
var Argument = "@&#";

var Result = URL.escapeString(Argument);

var ResultString = "URL.escapeStringO" + "\r\r"
"escapeString(@&#) = " + Result;

Dialogs. alert (ResultString) ;

getBase

Функция: URL. getBase ();

Описание: Возвращает абсолютный URL текущего

WMLScript-файла (без фрагмента).

Возвращаемое значение: Строка

Пример: Следующий сценарий использует функцию
URL.getBase () для получения URL файла, в котором находится сценарий:

extern function GetBaseTest()
{

var Result = URL.getBase();

var ResultString = "URL.getBase()" + "\r\r" +

"getBaseO = " + Result;

Dialogs.alert(ResultString);

}

getFragment

Функция: URL.getFragment (urlString);

Описание: Возвращает фрагмент, заданный во входной

URL-строке. При обнаружении некорректного
синтаксиса URL функция возвращает значение
invalid.

Аргумент: urlString = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
getFragment () для извлечения фрагмента
из URL

extern function GetFragmentTest()
{

var Result = URL.getFragment("");

var ResultString = "URL.getFragment()" + "\r\r" +
"The fragment is " + Result;

Dialogs.alert(ResultString);

}

getHost

Функция: URL.getHost(urlString);

Описание: Возвращает имя хост-системы, указанное во

входной URL-строке. Относительные URL не

преобразуются в абсолютные URL, поэтому имя
хост-системы в относительном URL будет возвращаться пустой строкой. При обнаружении
некорректного синтаксиса URL функция воз-
вращает значение invalid.

Аргумент: urlString = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL.getHostO для извлечения имени хост-системы из URL

extern function GetHostTest()

{

var Result = URL.getHost("#abed");

var ResultString = "URL.getHost()" + "\r\r" +
"The host is " + Result;

Dialogs.alert(ResultString);

}

getParameters

Функция: URL. getParameters (urlString);

Описание: Возвращает параметры, заданные во входной

URL-строке. При обнаружении некорректного
синтаксиса URL функция возвращает значение
invalid.

Аргумент: ur IStr ing = Строка

Возвращаемое значение: Строка или значение invalid

Пример: ; Следующий сценарий использует функцию

URL.getParameters() для извлечения списка
параметров из URL

extern function GetParametersTest()
{

var Result = URL.getParameters(" ,-2;3");

var ResultString = "URL.getParameters()" + "\r\r" +
"The parameters are " + Result;

Dialogs.alert(ResultString);

}

getPath

Функция: URL.getPath(urlString);

Описание: Возвращает путь, указанный во входной URL-

строке. При обнаружении некорректного син-

таксиса URL функция возрращает значение

invalid.

Аргумент: ur IStr ing = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL . getPath () для извлечения пути из URL

;

extern function GetPathTest()
{

var Result = URL.getPath("");
var ResultString = "URL.getPath()" + "\r\r" +

"The path is " + Result;

Dialogs.alert(ResultString);

{

getPort

Функция: URL.getPort(urlString);

Описание: Возвращает порт, указанный во входной URL-

строке. Если порт не указан, функция возвращает пустую строку. При обнаружении некоррект-
ного синтаксиса URL функция возвращает значение invalid.

Аргумент: urlString = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL. getPort () для извлечения номера порта из
URL ;2;3:

extern function GetPortTest()

var Result = URL.getPort("");

var ResultString = "URL.getPort()" + "\r\r" +

"The port is " + Result;

Dialogs.alert(ResultString);

getQuery

Функция: URL.getQuery(urlString);

Описание: Возвращает запрос, указанный во входной URL-
строке. Если запрос не указан, функция возвра-
щает пустую строку. При обнаружении некорректного синтаксиса URL функция возвращает
значение invalid.

Аргумент: urlString = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL.getQuery() для извлечения строки запроса
из URL &b=2:

extern function GetQueryTest()
{

var Result =
URL.getQuery("&b=2");

var ResultString = "URL.getQuery()" + "\r\r" +

"The query is " + Result; :

Dialogs.alert(ResultString);

)

getReferer

Функция: tJRL.getReferer();

Описание: Возвращает URL ресурса, который вызвал текущий WMLScript-сценарий.

Возвращаемое значение: Строка

Пример: Следующий сценарий использует функцию

URL. getReferer () для получения имени WML-
файла, вызвавшего сценарий:

extern function GetRefererTest()
{

var Result = URL.getReferer();

var ResultString = "URL.getReferer()" + "\r\r" +
"URL.getReferer = " + Result;

Dialogs.alert(ResultString);

{

getScheme

Функция: URL. getScheme (urlString);

Описание: Возвращает название протокола передачи данных, заданного во входной URL-строке. При об-
наружении некорректного синтаксиса URL
функция возвращает значение invalid.

Аргумент: urlString = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
URL. getScheme () для извлечения названия

протокола передачи данных, используемого в
- URL 1;2;3:

extern function GetSchemeTest()

{

var Result = URL.getScheme("");

var ResultString = "URL. getScheme ()" + "\r\r" +

"The scheme is " + Result;

Dialogs. alert (ResultString) ;
{

isValid

Функция: URL. isValid (urlString);

Описание: Возвращает логическое значение true, если
синтаксис входной URL-строки корректен и
false, если синтаксис не корректен.

Аргумент: urlString = Строка
Возвращаемое значение: Логическое значение

Пример: Следующий сценарий использует функцию

URL. isValid(), чтобы установить являются ли
строки "waplib.com" и "" корректными URL-
строками:

extern function IsValidTest ()

var Argumentl = "waplib.com"; ,
var Resultl = URL.isValid(Argumentl);

var Argument2 = "";
var Result2 = URL.isValid(Arguments);

var ResultString = "URL.isValid()" + "\r\r" +

"isValid(waplib.com) = " + Resultl + "\r" +
"isValid() = " + Result2;

Dialogs.alert(ResultString);

resolve

Функция: URL.resolve(baseURL, embeddedURL);

Описание: Возвращает абсолютный URL, получаемый из

указываемого базового URL и вложенного URL.


При обнаружении некорректного синтаксиса
URL функция возвращает значение invalid.

Аргументы: baseURL = Строка

embeddedURL = Строка

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию
URL.resolve{) для объединения двух аргументов в абсолютный URL:

extern function ResolveTest()

{

var Argumentl = "";
var Arguments = "Demos.wml";

var Result = URL.resolve(Argumentl, Arguments);

var ResultString = "URL.resolve()" + "\r\r" +

"The absolute URL is " + Result;

Dialogs.alert(ResultString);

}

unescapeString

Функция: URL.unescapeString(string);

Описание: Возвращает новую строку, получаемую из входной строки string путем замены всех ESCAPE-
последовательностей (таких, как те, что получаются с помощью функции URL.escapeString)
на символы, представляемые этими ESCAPE-

последовательностями. Если строка содержит

символы, которые не входят в набор знаков US-
ASCII, функция возвращает значение invalid.

Аргумент: string = Строка к
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

URL.unescapeStringO для декодирования

строки "%40%26%23":

extern function UnescapeStringTest()

{

var Argument = "%40%26%23";

var Result = URL.unescapeString(Argument);

var ResultString = "URL.unescapeStringO" + "\r\r" +

"unescapeString(%40%26%23) = " + Result;

Dialogs.alert(ResultString);

}

Библиотека WMLBrowser

Библиотека WMLBrowser


Библиотека WMLBrowser содержит набор функций, предназначенных для доступа
к составляющим информационного наполнения устройства (device context).

getCurrentCard

Функция: WMLBrowser. getCurrentCard ();

Описание: Возвращает URL карты, выполняемой в текущий

момент времени.

Возвращаемое значение: Строка

/ Пример: Следующий сценарий использует функцию

WMLBrowser.getCurrentCard() для получения
URL карты, выполняемой в текущий момент
времени:

extern function GetCurrentCardTest()

{
var Result = WMLBrowser.getCurrentCard();

var ResultString = "WMLBrowser.getCurrentCard()" + "\r\r"
"The current card is " + Result;

Dialogs.alert(ResultString); ....

}

getVar

Функция: WMLBrowser. getVar (name);

Описание: Возвращает значение переменной с указанным
именем. Если переменная не определена, функция возвращает пустую строку. Если синтаксис
имени переменной некорректен, функция возвращает значение invalid.

Аргумент: name = Строка

Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

WMLBrowser. getVar () для получения значения

переменной name, которая была определена в
WML-файле, вызвавшем сценарий:

extern function GetVarTestO
{
var Argument = "Name";^'
var Result = WMLBrowser.getVar(Argument);

var ResultString = "WMLBrowser.getVar()" + "\r\r" +

"The name is " + Result;

Dialogs.alert(ResultString);

Go

Функция: WMLBrowser.go(url);
Описание: Указывает, что должна загружаться и выполняться WML-страница по указанному URL WML-
страница не загружается до тех пор, пока не за-

кончится работа сценария. Функция возвращает

Пустую строку

Функции WMLBrowser. go О и WMLBrowser .prev()
замещают друг друга. Прежде чем сценарий
закончит свою работу, каждая из функций может
вызываться по нескольку раз. Однако сценарий
выполняет только последний вызов. Если по-
слeдний вызов устанавливает URL на пустую


строку, все запросы отменяются, и загрузка но вой карты или WML-страницы не выполняется.
Аргумент: url = Строка
Возвращаемое значение: Строка или значение invalid

Пример: Следующий сценарий использует функцию

WMLBrowser. go () для запуска WML-страницы
getvar.wml:

extern function GoTest()

{

var Argument = "getvar.wml";

var Result = WMLBrowser.go(Argument);

var ResultString = "WMLBrowser.go()" + "\r\r" +
"Ready to start " + "\r" +
"getvar.wml ";

Dialogs.alert(ResultString);
}

prev

Функция: WMLBrowser. prev ();

Описание: Указывает, что должна загружаться и выпол няться предыдущая карта. Карта не загружается

ДО тех пор, пока сценарий не завершит свою

работу. Функция возвращает пустую строку.

Функции WMLBrowser. go () и WMLBrowser. prev ()

замещают друг друга. Прежде чем сценарий

закончит свою работу, каждая из функций может

вызываться по нескольку раз. Выполняется

только последний вызов. Если последний вызов

устанавливает URL на пустую строку, все запросы

отменяются, и загрузка новой карты или WML-

страницы не выполняется.

Возвращаемое значение: Строка

Пример: Следующий сценарий использует функцию

WMLBrowser.prev() для,возврата на предыдущую

WML-страницу, которая в данном случае

представляет собой WML-страницу из примера
для функции WMLBrowser. go:

extern function PrevTestO

{

var Result = WMLBrowser.prev();

var ResultString = "WMLBrowser.prev()" + "\r\r" +
"Ready to go back one deck ";

Dialogs.alert(ResultString);

}

setVar

Функция: WMLBrowser.setVar(name, value);

Описание: Присваивает задаваемое значение value переменной с указываемым именем name и возвращает логическое значение true, если операция
выполнена успешно, и значение false, если
операция закончилась неудачей. Если синтаксис
имени переменной или указываемое значение

некорректны, функция возвращает значение

invalid.

Аргументы: name = Строка

value = любое значение

Возвращаемое значение: Логическое значение или значение invalid

Пример: Следующий сценарий использует функцию

WMLBrowser. setVar () для определения переменной Name в WML-странице, которая вызвала
сценарий:

extern function SetVarTestO

{
var Argumentl = "Name";

var Arguments = "Krissy";

var Result = WMLBrowser. setVar (Argumentl, Argument2) ;

var ResultString = "WMLBrowser. setVar ()" 4- "\r\r"
"Setting Name to Krissy";

Dialogs, alert (Resul tString) ;
)

Логические операции

Логические операции


Язык WMLScript поддерживает следующие базовые логические операции:


















































Оператор


Операция




&&


логическое "И" (AND)




II


логическое "ИЛИ" (OR)




!


логическое отрицание (NOT)











Оператор логического "И" (AND) вычисляет первый операнд и проверяет результат. Если получено логическое значение true (Истина), то результат операции будет равен значению второго операнда. Если получено логическое значение
false (Ложь) или недопустимое значение, то результат будет равен логическому
значению false или значению invalid (Недопустимое значение), и второй операнд не будет вычисляться. Также оператор логического "ИЛИ" (OR) вычисляет первый операнд и проверяет результат. Если получено логическое значение true или недопустимое значение, то результат операции будет равен логическому значению true или invalid.
Если получено логическое значение false, то результат операции будет равен

значению второго операнда.

Оператор Isvalid

Оператор Isvalid


Оператор isvalid возвращает логическое значение true, если тип выражения
относится к допустимым типам и false, если выражение имеет недопустимый
тип,

Оператор Typeof

Оператор Typeof


Язык WMLScript поддерживает следующие базовые типы данных: Boolean (логические значения), integer (целые числа), floating point (числа с плавающей
запятой), string (символьные строки), и invalid (недопустимые значения).
Оператор Typeof возвращает целочисленное значение, указывающее тип данного выражения. Оператор Typeof может принимать следующие значения:
























































Тип


Возвращаемое значение




Integer (целое число)





Floating point (число с плавающей запятой)


1




String (строка)


2




Boolean (логическое значение)


3




Invalid (недопустимое значение)


4








Операторы присваивания

Операторы присваивания


Операторы присваивания назначают переменным их значения. Язык описания
сценариев WMLScript поддерживает следующие операторы присваивания:








































































































Оператор


Операция




=


присваивание




+=


сложение чисел или объединение символьных строк и
присваивание




-=


вычитание и присваивание




*=


умножение и присваивание




/=


деление и присваивание




div=


целочисленное деление и присваивание




%=


получение остатка и присваивание (знак результата сов-
падает со знаком делимого)




"=


поразрядное смещение влево и присваивание




"=


поразрядное смещение вправо и присваивание




>"=


поразрядное смещение вправо с заполнением нулями и
присваивание




&-


поразрядная операция "И" (AND) и присваивание




/\=


поразрядная операция "исключающее ИЛИ" (XOR) и
присваивание




\-


поразрядная операция "ИЛИ" (OR) и присваивание








Операторы сравнения

Операторы сравнения


Язык WMLScript поддерживает следующие базовые операции сравнения:
































































Оператор


Операция




<


меньше




<- .,>


меньше или равно




==


равно












>=


больше или равно




>


больше




! =


не равно







Логическое значение true больше логического значения false.

Если один из операндов имеет недопустимое значение, результат
сравнения принимает значение invalid.

Строковые операторы

Строковые операторы


Язык WMLScript поддерживает объединение строк в качестве встроенной операции. Операторы "+" и "+=", используемые с символьными строками, выполняют
объединение символьных строк. Выполнение других операций со строками реализуется с помощью функций библиотеки String.

Условный Оператор

Условный Оператор


Язык WMLScript поддерживает условный оператор, который включает в свой состав три операнда, как показано ниже:

Result = argl ? arg2 : агgЗ;

Если первый операнд (argl) имеет значение true, то данный оператор присваивает результату (Result) значение второго операнда (arg2). Если первый операнд (argl) имеет значение false или недопустимое значение, то оператор присваивает результату (Result) значение третьего операнда (аrgЗ).



    Бизнес в интернете: Сайты - Софт - Языки - Дизайн