Explain the sample code of XML and modern CGI applications

Source: Internet
Author: User
Tags xslt xslt processor
The popularity of Perl is directly related to the vigorous development of the Internet. The powerful features and easy-to-expand features of Perl make it the most natural choice for developing CGI applications, and quickly become the preferred language for CGI scripts. CGI itself is not perfect. However, due to the popularity of many developers, CGI is still widely used, and there is no indication that it will "retire" in the near future ". Introduction

The popularity of Perl is directly related to the vigorous development of the Internet. The powerful features and easy-to-expand features of Perl make it the most natural choice for developing CGI applications, and quickly become the preferred language for CGI scripts. CGI itself is not perfect. However, due to the popularity of many developers, CGI is still widely used, and there is no indication that it will "retire" in the near future ".

The typical CGI: XMLApplication script consists of three parts: A small executable script that provides access to the application, a logic module that implements various management methods, and one or more XSLT style sheets based on the application status, the XSLT style sheet can convert the results returned by the module into a format that the browser can display to users.

The following example briefly describes the application of CGI: XMLApplication.

Example 1: cgi xslt Gateway

CGI: XMLApplication assume that the designers and developers involved in a project use the XSLT sample table to separate the logic and representation of the application, which makes the separation very direct, it will not affect the project. Developers only need to enable setStylesheet to return the position of the XSLT style table that conforms to the current application state. The transformation of the DOM tree created by the application, the transmission of XSLT parameters to the conversion engine, and the transmission of the content to the browser after the conversion are transparent to users.

To focus on this separation, our first example is not a traditional Web application, but a common XSLT Gateway, which can be added to the cgi-bin of the server, the directory tree of the entire XML content is converted to the format of the requested browser, which is transparent to users, style sheets, and document authors.

The first step is to establish the request to connect to the client and the CGI script of the application. We hope that the XML document can be easily viewed through the URL, and the hyperlinks between these documents can be easily created. Therefore, we will create a CGI script without an extension to use it as a node in the URL path, and all content on the right of the node will be explained in the virtual document environment that contains XML content. In this case, CGI is called the style Table selector.

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';

After loading appropriate modules and setting some variables that are valid throughout the script range, we began to add some domains to the % context passed to the class that processes the application logic. In this application, we only transmit the required URL (REQUEST entry) to the right of the script file path and the style key containing the data stored in the query parameter 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');

Finally, we created an instance of the logical class of the ingress gateway, and called its run method to process the request, using % context as the unique parameter.

my $app = XSLGateway->new();$app->run(%context);

The CGI script is complete. Next we will create a dedicated Gateway module to complete most of the work:

package XSLGateway;use strict;use vars qw(@ISA);use CGI::XMLApplication;use XML::LibXML;@ISA = qw(CGI::XMLApplication);

As I mentioned in the introduction, CGI: XMLApplication takes effect through event calls: execution of a given method in an application class depends on the input of a specified field (generally the name of the button used to submit the table .), Two call methods must be executed: selectStylesheet and requestDOM.

SelectStylesheet returns the full file system path of the relevant XSLT style table. To make it simple, we assume that the style sheet will be saved in a single directory. You can use the $ context-> {STYLE} field to provide other STYLE sheets to increase system flexibility.

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';}

Next, we need to create the requestDOM method, which will return the XML: LibXML DOM expression of the transmitted XML document. Because our gateway only applies to static files, we need to use XML: LibXML to parse the document and return the result tree.

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;}

So far, our CGI script can be safely run in the cgi-bin directory of the server, upload some XML documents and one or two XSLT style sheets in some appropriate directories. Next we can begin to test our work results. For localhost/cgi-bin/stylechooser/mydocs/somefile. xml requests will enable the Internet server to select mydocs/somefile from the/opt/www/htdocs/xmldocs/directory. use the default style table in/opt/www/htdocs/stylesheets. xsl converts the file and transmits it to the customer.

If necessary, we can expand this basic framework. for example, you can select the CGI script program in the style sheet to add some search components and select the appropriate style sheet, you can set or read HTTP cookies to modify the website.

Example 2: a simple shopping system

In this example, we will use CGI: XMLApplication to create a simplified Web application and shopping system.

As in the previous example, there are still very few CGI-BIN-related parts in this application. All we need to do is initialize the CustomerOrder application class and call its run () method. This time, Vars in CGI. pm is used as the PARAMS domain of % context:

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);

In this example, we assume that the product information in this application is stored in the relational database, and the product list is not too long, so that we do not have the trouble of displaying the relevant information on multiple screens in the application: the user enters the main data input screen of the number of purchased products, and displays the purchase order content and the confirmation screen of the total price of the selected items, the prompt that the order has been processed is displayed. For the sake of simplicity, we have no input concerning shipping and financial data here.

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);

After loading necessary modules and definitions of classes inherited from CGI: XMLAplication, we start to create event calls related to various states in the application. First, we must register these events by creating the registerEvents () method. In this example, we will register the order_confirm and order_send methods to set the SCREENSTYLE field in % context. Later, we will use this attribute to define which of the three XSLT style sheets should be used to display client data.

It should be noted that these events will be mapped to the actual subroutines implementing them, and the naming rules of subroutines are event _ <事件名> For example, the order_confim event is executed by event_order_confim. In addition, it should be noted that the selection of various events is based on the ability of CGI: XMLApplication to find a table parameter with the same name as the registration event. For example, to execute the order_confirm event, the table component must contain a table domain named order_confirm that submits non-null values.

# Event registration and event calling

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';}

If no other things are requested, event_default is executed by default. In this example, we only use it to set the SCREENSTYLE field as a proper value.

sub event_default {my ($self, $context) = @_;$context->{SCREENSTYLE} = 'order_default.xsl';}

Each request will execute the event_init method and always execute it before other methods, which makes it very suitable for initializing the parts used by other events in the application. In this example, we use it to return the initial DOM tree of the product information obtained from the database using the fetch_recordset () method.

sub event_init {my ($self, $context) = @_;$context->{DOMTREE} = $self->fetch_recordset();}

After the state-handler method is complete, we need to execute the required selectStylesheet and requestDOM methods.

As in the first example, we assume that the style sheets of all applications are stored in the same directory on the server. All we need to do is return the route specified by the value of $ context-> {SCREENSTYLE} and add it to the end.

# app config and helperssub selectStylesheet {my ($self, $context) = @_;my $style = $context-> {SCREENSTYLE};my $style_path = '/opt/www/htdocs/stylesheets/cart/';return $style_path . $style;}

Before studying the requestDOM processing program, we will first study the fetch_recordset helper method in detail.

Remember that the job we need to do is to select information about the product to be ordered from a relational database, but the data transmitted to the XSLT processor must be a DOM tree. In this example, we use XML: Generator: DBI instead of programming to generate the SAX data from the data obtained by executing the SQL SELECT statement. To create a required DOM tree, you must create an instance of XML: LibXML: SAX: Builder (which creates the XML: LibXML DOM tree from the SAX event.

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'tbe 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;}

The fetch_recordset method completes another very important task, but the DOM tree returned by the fetch_recordset method only contains part of the information we want to send to the customer. we must also obtain the number of products that the user inputs. In addition, you also need to provide a total of purchased products.

sub requestDOM {my ($self, $context) = @_;my $root = $context-> {DOMTREE}->getDocumentElement();my $grand_total = '0';

To make the current order quantity part of a larger document, we traverse all product elements and add and subelements to each line. The value can be obtained from the $ context-> {PARAMS} domain.

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);}

Finally, we will add some meta information about the order by adding an element to the root element with the element, which contains the total value of the currently selected goods.

$grand_total ||= '0.00';my $info = XML::LibXML::Element->new('instance-info');$info- >appendTextChild('order-total', $grand_total);$root- >appendChild($info);return $context->{DOMTREE};}

Careful readers may have noticed that our very simple application did not do anything practical in the order_send method. Deciding how to process the data is the most relevant part of the product ordering application to a specific shopping website.

Conclusion

CGI: XMLApplication provides a clear and modular method for isolating system content and representation in CGI script program programming, it is worth some research. In addition, it helps us avoid getting stuck with some details and focus on solving the main problems.

The above is a detailed description of the sample code of XML and modern CGI applications. For more information, see other related articles in the first PHP community!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.