詳解XML與現代CGI應用程式的範例程式碼
簡介
Perl的普及與網路的蓬勃發展有直接的關係。 Perl強大的功能 和容易擴充的特性使得它成為開發CGI應用最自然的選擇,並由此迅速地成為CGI 腳本的首選語言。 CGI本身並非十全十美。但由於得到了許多開發商的青睞,CGI 的應用至今仍然十分廣泛,而且沒有跡象表明在近期會「退休」。
典型的CGI::XMLApplication腳本包括三個部分:一個很小的提供對該應用程式存取支援的可執行腳本、實作各種管理者方法的邏輯模組、根據應用程式狀態可能有一個或多個XSLT樣式表,XSLT樣式表能夠將模組傳回的結果轉換成瀏覽器可以顯示給使用者的格式。
下面我們透過例子來簡單介紹 CGI::XMLApplication的應用。
範例1:CGI XSLT網關
CGI::XMLApplication假定,參與一個專案的設計和開發人員使用XSLT樣式表分離應用程式的邏輯和表示,這樣可以使這種分離顯得非常直接,也不會對專案帶來影響。開發人員只要能夠使setStylesheet傳回符合目前應用程式狀態的XSLT樣式 表的位置即可。應用建立的DOM樹的轉換、XSLT參數向轉換引擎的傳遞、轉換後內 容向瀏覽器的傳輸對使用者而言都是透明的。
為了重點說明這種分離,我們的第一個例子不是傳統意義上的Web應用,而是一個通用的XSLT網關,它可以添加到伺服器的cgi-bin中,將整個XML內容的目錄樹轉換為符合請求的瀏覽器的格式,而這一切對於使用者、樣式表和文件的作者而言也都是透明的。
第一步是 建立連線客戶端的請求和應用的CGI腳本。我們希望XML文件能夠方便地通過URL瀏 覽,並使建立這些文件間的超連結非常直觀。因此,我們將建立一個沒有副檔名 的CGI腳本,以便將它作為URL路徑中的一個節點,節點右邊的所有內容將在包含 XML內容的虛擬文件環境中進行解釋。在這種情況下,我們將CGI稱為樣式表選 擇者。
use strict; use lib '/path/to/secure/webapp/libs'; use XSLGateway; use CGI qw(:standard);my $q = CGI->new(); my %context = (); my $gateway_name = 'stylechooser';
在載入合適的模組和設定一些在整個腳本範圍內有效的變數後,我們開始向被傳遞給處理該應用邏輯的類別的%context中添加一些域。在這個應用軟體中,我們只傳輸要求的指向腳本檔案 路徑右邊的URL(REQUEST條目)和包含有儲存在查詢參數style中的資料的STYLE 關健字。
$context{REQUEST} = $q->url(-path => 1); $context{REQUEST} =~ s/^$gateway_name/?//; $context{REQUEST} ||= 'index.xml'; $context{STYLE} = $q->param ('style') if $q->param('style');
最後,我們 建立了XSLGateway邏輯類別的一個實例,並透過呼叫其run方法處理請求,將% context作為唯一的參數。
my $app = XSLGateway->new(); $app->run(%context);
CGI腳本就完成了。下面我們建立完成大部分工作的XSLGateway模組:
package XSLGateway; use strict; use vars qw(@ISA); use CGI::XMLApplication; use XML::LibXML; @ISA = qw(CGI::XMLApplication);
像我在簡介中提到的那樣,CGI::XMLApplication透過事件呼叫運作:應用程式類別中一個給定的方法的執行依賴於一個指定域的輸入(一般情況下是用來提交表格的按鈕的名字。),必須執行二種呼叫方法:selectStylesheet和requestDOM方法。
selectStylesheet傳回相關的XSLT樣式表的全檔案系統路徑。為了簡單起 見,我們假定樣式表將會保存在單一的目錄中。我們可以透過$context-> {STYLE}域提供其他的樣式表,從而增加系統的靈活性。
sub selectStylesheet { my $self = shift; my $context = shift; my $style = $context->{STYLE} || 'default'; my $style_path = '/opt/www/htdocs/stylesheets/'; return $style_path . $style . '.xsl'; }
下一步,我們需要 建立requestDOM方法,該方法將傳回被傳輸的XML文件的XML::LibXML DOM表達式 。由於我們的網關只適用於靜態文件,我們需要使用XML::LibXML對文檔進行解析 ,並傳回結果樹。
sub requestDOM { my $self = shift; my $context = shift; my $xml_file = $context->{REQUEST} || 'index.xml'; my $doc_path = '/opt/www/htdocs/xmldocs/'; my $requested_doc = $doc_path . $xml_file; my $parser = XML::LibXML->new; my $doc = $parser->parse_file($requested_doc); return $doc; }
至此,我們的CGI腳本已經可以安全地在伺服器的cgi-bin目錄中安全 地運行了,並在一些適當的目錄中上載一些XML文檔和一個或二個XSLT樣式表。下 面我們就可以開始檢驗我們的工作成果了。 localhost/cgi- bin/stylechooser/mydocs/somefile.xml的請求將會使互聯網伺服器從/opt/www/htdocs/xmldocs/目錄中選取mydocs/somefile.xml文件,使用/opt/www/htdocs/stylesheets /中的樣式表default.xsl對該檔案進行轉換,並將它傳輸給客戶。
如果需要,我们可以扩充这一基本的框架,例如,可以 在样式表选择CGI脚本程序添加一些查找组件,选择合适的样式表,可以设置或读 取HTTP cookies,对网站进行修饰。
例2:一个简单的购物系统
在 该例子中,我们将使用CGI::XMLApplication创建一个简化的Web应用程序,购物 系统。
与上个例子相同,这个应用程序中与CGI-BIN有关的部分仍然非常 地少。我们所需要作的只不过是初始化CustomerOrder应用类并调用它的run()方 法。这次,我们将CGI.pm中Vars作为%context的PARAMS域:
use strict; use CGI qw(:standard); use lib '/path/to/secure/webapp/libs'; use CustomerOrder; my $q = CGI->new(); my %context = (); $context{PARAMS} = $q- >Vars; my $app = CustomerOrder->new(); $app->run(% context);
在这个例子中,我们假定该应用中的产品信息存储在关 系数据库中,产品清单不是太长,使我们在应用中不会出现多屏才能显示相关信 息的麻烦:用户输入订购的产品数量的主要数据输入屏,显示订购单内容和所选 物品总价格的确认屏,显示订单已经处理的提示。为了简单起见,我们在这里没 有涉及送货和财务数据的输入等问题。
package CustomerOrder; use strict; use vars qw(@ISA); use CGI::XMLApplication; use XML::LibXML::SAX::Builder; use XML::Generator::DBI; use DBI; @ISA = qw (CGI::XMLApplication);
在加载必要的模块和定义从 CGI::XMLAplication中继承的类后,我们开始创建应用中与各种状态有关的事件 调用。首先,我们必须通过创建registerEvents()方法注册这些事件。在本例中 ,我们将注册order_confirm 和order_send方法,这二个方法设置%context中的 SCREENSTYLE域。稍后,我们将利用该属性定义在显示客户端的数据时应该使用三 个XSLT样式表中的哪一个。
需要注意的是,这些事件将被映射到实现它们 的实际的子程序中,子程序的命名规则是event_<事件名>,例如, order_confim事件是由event_order_confim执行的。另外,还需要注意的是,各 种事件的选择是由CGI::XMLApplication根据其查找一个与注册事件同名的表格参 数的能力进行的。例如,要执行order_confirm事件,表格组件中必须包含一个提 交非空值的名字为order_confirm的表格域。
# 事件的注册和事件调用
sub registerEvents { return qw( order_confirm order_send ); } sub event_order_confirm { my ($self, $context) = @_; $context->{SCREENSTYLE} = 'order_confirm.xsl'; } sub event_order_send { my ($self, $context) = @_; $context->{SCREENSTYLE} = 'order_send.xsl'; }
如果没有请求执行其他的事 件,则缺省地执行event_default。在本例中,我们只使用它将SCREENSTYLE域设 定为一个合适的值。
sub event_default { my ($self, $context) = @_; $context->{SCREENSTYLE} = 'order_default.xsl'; }
每次请求都会执行 event_init方法,而且总是在其他方法之前执行它,这使得它非常适合对应用中 被其他事件使用的部分进行初始化。在本例中,我们使用它返回利用 fetch_recordset()方法从数据库中获取的产品信息的、最初的DOM树。
sub event_init { my ($self, $context) = @_; $context->{DOMTREE} = $self->fetch_recordset(); }
state-handler方法完成后,我们需要执行必需的 selectStylesheet和requestDOM方法。
与在第一个例子中一样,我们假设 所有的应用的样式表都存储在服务器上相同的目录中。我们所需要作的是返回 $context->{SCREENSTYLE}的值所指定的路线,并添加到末尾。
# app config and helpers sub selectStylesheet { my ($self, $context) = @_; my $style = $context-> {SCREENSTYLE}; my $style_path = '/opt/www/htdocs/stylesheets/cart/'; return $style_path . $style; }
在研究requestDOM处理程序之前,我们先来详细 地研究fetch_recordset helper方法。
需要记住的是,我们要做的工作是 从一个关系数据库中选择所订购产品的有关信息,但传递给XSLT处理器的数据必 须是DOM树。在本例中,我们不通过编程的方法,而是利用XML::Generator::DBI ,它能够从执行SQL SELECT语句得到的数据中生成SAX数据。创建要求的DOM树就 是建立XML::LibXML::SAX::Builder(它从SAX事件中创建XML::LibXML DOM树)的 实例。
sub fetch_recordset { my $self = shift; my $sql = 'select id, name, price from products'; my $dbh = DBI->connect('dbi:Oracle:webclients', 'chico', 'swordfish') || die "database connection couldn't be initialized: $DBI::errstr n"; my $builder = XML::LibXML::SAX::Builder->new(); my $gen = XML::Generator::DBI->new(Handler => $builder, dbh => $dbh, RootElement => 'document', QueryElement => 'productlist', RowElement => 'product'); my $dom = $gen->execute($sql) || die "Error Building DOM Treen"; return $dom;}
fetch_recordset方法完成了另一项很重要的任务,但它返回的 DOM树只包含我们想向客户发送信息的一部分,我们还必须获取用户输入的产品数 量,另外,还需要提供一个订购产品的总计。
sub requestDOM { my ($self, $context) = @_; my $root = $context-> {DOMTREE}->getDocumentElement(); my $grand_total = '0';
为了将当前的订货数量作为更大的文档的一部分, 我们将遍历所有的产品元素,并在每行中添加和子元素。的值可以从$context- >{PARAMS}域获得。
foreach my $row ($root->findnodes ('/document/productlist/product')) { my $id = $row- >findvalue('id'); my $cost = $row->findvalue ('price'); my $quantity = $context->{PARAMS}->{$id} || '0'; my $item_total = $quantity * $cost; $grand_total += $item_total; # add the order quantity and item totals to the tree. $row->appendTextChild('quantity', $quantity); $row->appendTextChild('item-total', $item_total); }
最后,我们将增加一些有关订单的元信息 ,方法是在具有元素的根元素中添加一个元素,该元素中包含有当前所选货物的 总价值。
$grand_total ||= '0.00'; my $info = XML::LibXML::Element->new('instance-info'); $info- >appendTextChild('order-total', $grand_total); $root- >appendChild($info); return $context->{DOMTREE}; }
细心的读者可能已经注意到,我们这个非常简单的应用程序在 order_send方法中没有作任何实际的事。决定如何处理这些数据是产品订购应用 程序中与具体的购物网站最有关的部分。
结束语
CGI::XMLApplication在CGI脚本程序的编程中提供了一种清晰的、模块化 的隔离系统的内容和表示的方法,单就这一点,就值得我们对它进行一番研究。 此外,它还可以使我们避免纠缠于一些细节问题,而集中精力解决主要的问题。
【相关推荐】
#2. 分享在IIS上以CGI方式執行Python腳本的實例教學
#5 . 什麼是CGI?詳細介紹Python CGI程式設計
##
以上是詳解XML與現代CGI應用程式的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如果您在Windows11中使用照片應用程式進行影像編輯時遇到無法儲存變更的錯誤,本文將為您提供解決方案。無法儲存變更。保存時發生錯誤。請稍後再試。通常會出現這種問題的原因包括權限設定不正確、檔案損壞或系統故障。因此,我們經過深入研究,整理出一些最有效的故障排除步驟,以幫助您解決此問題,並確保您可以繼續在Windows11裝置上無縫使用MicrosoftPhotos應用程式。修復Windows11中無法保存更改照片應用程式的錯誤許多用戶在不同的論壇上一直在談論MicrosoftPhotos應用程式錯

在Windows系統中,照片應用程式是一個方便的方式來檢視和管理照片和影片。透過這個應用程序,用戶可以輕鬆存取他們的多媒體文件,而無需安裝額外的軟體。然而,有時用戶可能會碰到一些問題,例如在使用照片應用程式時遇到「無法開啟此文件,因為不支援該格式」的錯誤提示,或在嘗試開啟照片或影片時出現文件損壞的問題。這種情況可能會讓使用者感到困惑和不便,需要進行一些調查和修復來解決這些問題。當用戶嘗試在Photos應用程式上開啟照片或影片時,會看到以下錯誤。抱歉,照片無法開啟此文件,因為目前不支援該格式,或該文件

AppleVisionPro頭戴式裝置本身與電腦不相容,因此您必須將其設定為連接到Windows電腦。自推出以來,AppleVisionPro一直備受追捧,擁有其尖端功能和廣泛的可操作性,很容易理解原因。雖然您可以對其進行一些調整以適應PC,並且其功能在很大程度上取決於AppleOS,因此其功能將受到限制。如何將AppleVisionPro連接到我的電腦? 1.驗證系統要求你需要最新版本的Windows11(不支援自訂電腦和Surface設備)支援64位元2GHZ或更快的快速處理器高效能GPU,最

當小夥伴的電腦缺少一定的檔案之後就會出現應用程式無法正常啟動0xc000012d的情況,其實只要重新下載檔案並安裝就可以很好的解決了喲。應用程式無法正常啟動0xc000012d:1、首先使用者需要下載「.netframework」。 2、然後找到下載地址並將其下載到自己的電腦。 3、然後在桌面雙擊開始運作。 4.安裝完成之後傳回先前錯誤的程式位置,再次開啟程式即可。

MicrosoftPaint在Windows11/10中不起作用嗎?嗯,這似乎是一個常見的問題,我們有一些很好的解決方案來解決這個問題。用戶一直抱怨說,當試圖使用MSPaint時,無法工作或打開。應用程式中的捲軸不起作用,貼上圖示沒有顯示,崩潰,等等。幸運的是,我們收集了一些最有效的故障排除方法來幫助您解決MicrosoftPaint應用程式的問題。為什麼MicrosoftPaint不起作用? MSPaint無法在Windows11/10PC上運行的一些可能原因如下:安全標識符已損壞。掛起的系統

許多用戶一直在抱怨,每次嘗試使用MicrosoftTeams登入時都會遇到錯誤代碼caa90019。儘管這是一款方便的溝通應用程序,但這種錯誤卻很普遍。修正MicrosoftTeams錯誤:caa90019在這種情況下,系統顯示的錯誤訊息為:「抱歉,我們目前遇到問題。」我們已準備好終極解決方案清單,可協助您解決MicrosoftTeams錯誤caa90019。初步步驟以管理員身分執行清除MicrosoftTeams應用程式快取刪除settings.json檔案從憑證管理員中清除Microso

iPhone上的Shazam應用程式有問題? Shazam可協助您透過聆聽歌曲找到歌曲。但是,如果Shazam無法正常工作或無法識別歌曲,則必須手動對其進行故障排除。修復Shazam應用程式不會花費很長時間。因此,無需再浪費時間,請按照以下步驟解決Shazam應用程式的問題。修正1–禁用粗體文字功能iPhone上的粗體文字可能是Shazam無法正常運作的原因。步驟1–您只能從iPhone設定執行此操作。所以,打開它。步驟2–接下來,開啟其中的「顯示和亮度」設定。步驟3–如果您發現啟用了“粗體文本

XML檔可以用PPT開啟嗎? XML,即可擴展標記語言(ExtensibleMarkupLanguage),是一種廣泛應用於資料交換和資料儲存的通用標記語言。與HTML相比,XML更加靈活,能夠定義自己的標籤和資料結構,使得資料的儲存和交換更加方便和統一。而PPT,即PowerPoint,是微軟公司開發的一種用於創建簡報的軟體。它提供了圖文並茂的方
