Content-Generation Technologies

Content-Generation Technologies

Now that we have looked at the common wireless markup languages, it is time to look at the technologies most commonly used to create dynamic wireless applications. Each technology will provide you with a mechanism to interact with enterprise data, as well as server-side business logic so you can create interactive, data-driven wireless applications. Each technology will also allow you to create content specific to the device making the request. So, for example, you could have HDML, WML, and XHTML content all being driven from the same application on the server. This type of capability is of particular interest if you are deploying your application to a broad audience or to an audience on different continents.

Deciding which solution is best is not an easy task. The solution that is ideal for one application may not be suitable for another. The decision often comes down to the developer's skill set, in combination with the technology currently being used in the organization. In most cases you will find that the technology used to generate wireless content is the same that is used for creating HTML-based desktop applications.

We are going to look at five different technologies: CGI with Perl, Java servlets, JavaServer Pages, Active Server Pages, and XML with XSL stylesheets. These technologies can be divided into two categories: code-driven and page-driven. Both Perl and Java servlets are code-driven, with the markup language embedded into source code. These technologies are usually best suited for applications that require integration with server-side application logic, but do not require sophisticated user interfaces. The page-driven technologies embed source code into the markup language. Both JavaServer Pages and Active Server Pages fall into this category. They are good choices for applications in which there is a significant amount of client code, but perhaps not as much usage of server-side business logic. Finally we have XML with XSL stylesheets, which can be driven either by a code-centric or page-centric approach.

Keep in mind that these observations are only guidelines, and that each technology can be adapted for a variety of applications. As mentioned, the final decision often will be based on the skills of the developer, or development team, responsible for implementing the solution.

Common Gateway Interface (CGI) with Perl

The Common Gateway Interface (CGI) is one of the most widely used server-side technologies for Web development; it is supported on almost every Web server. CGI comprises a set of commands for communicating between a Web server and a program that processes information from a Web page. It was the first technology available for making Web sites dynamic. Unlike static content that is served up in a text format, CGI applications are executed on the server in real time, so that content can be generated on the fly. Many of the early dynamic Web sites used CGI to obtain user input, access enterprise databases, and return some result back to the browser. In order to communicate with other applications, there had to be a form of business logic associated with the application. CGI enables this program intelligence to be written in almost any language, though the more popular ones are C/C++, FORTRAN, Java, and Perl. Out of these and many others, Perl is the language most often used for creating CGI applications.

Now in its sixth version, Perl has a quite a history. Its first version was released at the end of 1987, long before people were thinking of building Internet applications. Perl is based on the C programming language, and is developed and maintained by thousands of developers, along with its creator, Larry Wall. Perl is an interpreted language, meaning that it does not have to be compiled into native bytecodes to execute. This has many benefits over compiled languages like C or FORTRAN, making it easier to debug, modify, and maintain.

Perl has grown in popularity for Web programming because it makes it possible to create quick and effective interactive applications. Listing 13.5 shows an example of a Perl application that outputs a WML deck. The code in this example is quite simple: It outputs Hello Wireless World! to the screen of the wireless device; nevertheless, it serves to demonstrate how the language is constructed. The first line of all Perl programs has to be the location of the Perl interpreter. In our example, it is located in the user/bin/perl directory. The second line specifies the content type. For most Web applications, this would be specified as text/html, but for WML applications, it is text/vnd.wap.wml. After that is taken care of, we are left to create our WML code for the application. Notice that, similar to C, each line ends with a semicolon. In this example, the code is not very dynamic at all. Each line uses a print statement to output some WML code. Lines 5 to 8 in the example create a WML deck with a single card that outputs "Hello Wireless World!"

Listing 13.5: Perl CGI application.
Start example
1.   #!/usr/bin/perl
2.   print "Content-type: text/vnd.wap.wml\n\n";
3.   print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
4.   print "<!DOCTYPE wml PUBLIC \"-//WAPFORUM//DTD WML 1.1//EN\"
\" http://www.wapforum.org/DTD/wml_1.1.xml\">\n";
5.   print "<wml>\n";
6.   print "   <card id='card1'>\n";
7.   print "      <p>Hello Wireless World!</p>\n";
8.   print "   </card>\n";
9.   print "</wml>\n";
End example

There are other ways that this can be accomplished. One is to use a string variable to hold the code, then flush it to the screen all at once. Another is to create functions that would piece the WML together in logical units, inserting dynamic data where required. The specifics of Perl are beyond the scope of this overview, but the point is that Perl is indeed a complete programming language, capable of creating very advanced, dynamic applications.

The major disadvantage to using CGI for dynamic content generation is its scalability. Each request received by the Web server spawns a new process, creating its own set of environment variables, a separate instance of any required runtime environment, a copy of the program, and a block of memory for the program to use. In the case of Perl CGI programs, the Perl interpreter is invoked, requiring additional resources. For sites that do not get much traffic, this may not be a concern, but for sites that get thousands of hits a day, this can lead to significant performance problems and, potentially, system failure.

In response to the poor performance of CGI applications, Microsoft and Netscape each developed a proprietary set of APIs that could be used to write server applications. These APIs, known as Internet Server API (ISAPI) and Netscape Server API (NSAPI) did help with performance, but they also introduced new problems. The first problem is that these technologies are proprietary. When an application is created, it can only run on the platform for which it was developed. Moving the programs to a different environment is a costly task. The second problem is that the logic runs in the same process as the Web server. If the program causes a memory access violation, there is a chance it could crash the entire Web server, rather than just the one application.

The scalability problems of CGI and the proprietary nature of ISAPI and NSAPI led to the development of new technologies that are better suited for cross-platform server-side development.

Java Servlets

In 1998, Sun Microsystems introduced a technology called Java Servlets that addressed both the performance and the cross-platform obstacles that plagued earlier server-side technology. Written in Java, the servlet code is compiled into bytecodes that are interpreted by a Java Virtual Machine (JVM) on the Web server. This allows the servlet code to be moved to any server that has a JVM. Also, when a request is issued to a servlet, it creates a new thread to process the request. When the servlet has done its job, it is reused by other clients, meaning it does not have to be destroyed and re-created for each client request. This has a positive impact on both performance and scalability.

Servlets use a code-driven approach to create wireless content. This is similar to the CGI Perl approach in that each line of the WML or other markup language is output using a print statement, or to be precise, an out.println() statement. The code around the lines containing the output control the program flow, often making calls to other Java classes or Enterprise JavaBeans to execute logic or access enterprise data. This approach works very well for applications with simple user interfaces and for developers who prefer to program in Java instead of a wireless markup language.

The Java Servlet API is part of the Java 2 Platform, Enterprise Edition (J2EE). This gives servlets the capability to easily access other J2EE APIs, including Enterprise JavaBeans for component logic, JDBC for database access, and JMS for messaging integration. All of these technologies are commonly executed using application server technology. Most of the leading application servers on the market have full J2EE support, making them very capable platforms for creating Internet applications.

Over the past few years, the concept of a wireless application server has also emerged. These are usually application servers that provide specific class libraries, or frameworks, for creating wireless Internet applications. We are now going to look at an example of a Java servlet that generates XHTML code. (Chapter 14 has more information about the capabilities that are provided in wireless focused products.)

In Listing 13.6 is the complete Java code for a servlet that takes an HTTP GET request from the client and returns a simple XHTML form. The top five lines contain the import statements required for the class to compile. Line 6 contains the class definition. This class is called HelloWorld, and it extends HttpServlet. By extending HttpServlet, the class automatically gets servlet functionality without having to implement the entire Serlvet interface. HttpServlet implements the Servlet interface for us, saving us extra coding time. Within our HelloWorld class, we then move directly into the doGet(...) method, which is called every time a GET request is made to the servlet. If we wanted to do some initialization, we could have included an init() method as well. The servlet engine calls this method implicitly when the servlet is invoked. For our example, we did not require any initialization, so there is no init() method. If we were accessing a database or other data source, we might have included the connection to the data source in the init() method.

Listing 13.6: Java servlet that outputs XHTML.
Start example
1.  // Import the required Java libraries
2.  import java.io.*;
3.  // Import the required Java Servlet libraries
4.  import javax.servlet.*;
5.  import javax.servlet.http.*;
6.  public class HelloWorld extends HttpServlet
7.  {
8.    public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
9.    {
10.     res.setContentType("text/html");
11.     PrintWriter out = res.getWriter();
12.     out.println("<!DOCTYPE html PUBLIC \"-//OPENWAVE//DTD XHTML
Mobile 1.0//EN\" \" http://www.openwave.com/dtd/xhtml-mobile10.dtd\">");
13.     out.println("<html
xmlns=\"http://www.w3.org/1999/xhtml\"xml:lang=\"en\">");
14.     out.println("<head>");
15.     out.println("<title>XHTML Servlet</title>");
16.     out.println("</head>");
17.     out.println("<body>");
18.     out.println("<p align=\"left\"><b>Hello XHTML Wireless
World!</b></p>");
19.     out.println("</body>");
20.     out.println("</html>");
21.   }
22. }
End example

On line 8 you can see the doGet method takes two parameters, HttpServletRequest and HttpServletResponse. HttpServletRequest is used to get information from the client, such as the MIME type. The HttpServletResponse is used to send information back to the client; in this case, we are setting the content type to text/html, as shown on line 10, then outputting the XHTML content. We also use the HttpServletResponse object to get the PrintWriter for our output stream.

On lines 12 through 20 we output the XHTML code. You can see that each line of XHTML is output using the out.println(...) method. The XHTHML code generated by this servlet is quite simple. It would display "Hello XHTML Wireless World!" on the XHTML browser. Unfortunately, even for such straightforward code, the Java servlet is somewhat difficult to read.

The quotation marks in the XHTML code can confuse the Java compiler, so each quotation mark has to be escaped using a backslash. Line 12 demonstrates how confusing the XHTML code can become once it is embedded into the Java code and the escape characters are added. This demonstrates one of the drawbacks of using Java servlets for creating wireless content. Even a very simple application requires developers to have Java programming skills, and when they do, the resulting code is still quite difficult to develop and maintain. Each time the markup language is changed, the servlet has to be edited and recompiled. This could adversely affect other parts of the application.

Using Java servlets does, however, offer many advantages, namely a cross-platform, high-performance way to extend the capabilities of a Web server to provide dynamic wireless content. With wide platform support, servlets are a very attractive technology for those who are comfortable programming in Java.

JavaServer Pages

JavaServer Pages (JSPs) are ideal for developers who want the cross-platform and performance benefits of Java servlets but do not want to program using Java. JSPs are a page-driven technology that allows Java code to be embedded in the markup language, rather than the markup language being embedded in Java as with servlets. This allows Web developers to rapidly create information rich, dynamic Web pages that are easy to maintain. Unlike Java servlets, JavaServer Pages separate the presentation logic from the business logic, allowing changes to the user interface without affecting the program logic. This allows Web designers to create the user interface with their favorite Web development tools, while Java programmers create the business logic.

The contents of a JSP page can be divided into two main categories: elements and template data. The elements are XML-like tags that are used to control program flow and encapsulate Java logic. There are five types of elements that you may use: directives, declarations, scriptlets, expressions, and actions. All of these are processed on the server, which then performs the desired task. The template data is everything other than the elements, usually your markup language. The templates are ignored by the engine that processes the JSPs since they do not provide any server-side logic. In this way, you can create sophisticated Web applications with embedded logic to perform more advanced tasks. Let's look at a sample JSP to get an idea of what this means.

Listing 13.7 contains the source code for a complete JSP that outputs HDML code. As you can see, the majority of the code is an HDML template into which we can insert various JSP elements. Let's look at some of the more interesting segments of this example.

Listing 13.7: Java Server Page that outputs HDML code.
Start example
1.  <%@ page contentType="text/x-hdml"%>
2.  <%@ page language="java"%>
3.  <!-- string declaration -->
4.  <%! String item1_id="101"; %>
5.  <%! String item2_id="102"; %>
6.  <%! String item3_id="103"; %>
7.  <!-- HDML code to display Inventory list -->
8.  <HDML VERSION="3.0">
9.    <display name="item1">
10.     <action type="accept" task="go" dest="#item2" label="Skip">
11.     <action type="soft1" task="go"
dest="details.jsp?product_id=<%=item1_id %>" label="Details">
12.     Sony-TRV30 Digital Video Camcorder
13.   </display>
14.   <display name="item2">
15.     <action type="accept" task="go" dest="#item3" label="Skip">
16.     <action type="soft1" task="go"
dest="details.jsp?product_id=<%=item2_id %>" label="Details">
17.     Hitachi-VMD875L Digital 8 Camcorder
18.   </display>
19.   <display name="item3">
20.     <action type="accept" task="go" dest="#finish" label=" finish">
21.     <action type="soft1" task="go"
dest="details.jsp?product_id=<%=item3_id %>" label="Details">
22.     Sony-DCR-IP7BT Micro MV Network Handycam
23.   </display>
24.   <display name="finish">
25.     <action type="accept" task="return" label="Done">
26.     <!-- Java scriptlet -->
28.     <%
29.         String username = request.getParameter("user");
30.         out.println("Thank-you for visiting "+ username);
31.     %>
32.   </display>
33. </HDML>
End example

One of the most common problems of getting HDML (or WML, for that matter) to work with a JSP is related to the MIME type. The first line of your JSP file has to be the JSP page directive setting the contentType attribute. If this line is not present, then the microbrowser will not be able to display the content. The other attribute that needs to be set for the page directive is the language. Java is the only language supported in the current specification, so that is what we set it to. There are many other attributes, such as import, extends, session, errorPage, and buffer, that you may want to look into when creating your own JSPs.

On line 3 is a comment. You can add comments throughout your JSP to help a reader understand the code. Keep in mind that these are not Java comments and therefore are not removed on the server. So do not put anything in this type of comment that you do not want to be seen by the client. In this case, the comment is helpful for the JSP editor, but will not make any sense to those viewing it in a browser, since they will not see the code in lines 4 to 6. These lines contain JSP declarations. Declarations start with <%! and end with %>. In between, you can enter Java code to set variable values and other declarations. In our example, we are setting three strings with default values. Each line of Java code in a declaration ends with a semicolon.

Now we get into the HDML code. Lines 8 to 33 comprise the HDML template. The HDML code in this example consists of four cards. The first three display inventory information; the fourth uses Java code to output a personalized message. Let's look at the first card, which is on lines 9 to 13. After setting up the name of the card in line 9, we define the actions for the two soft keys on the device. On line 10, the accept key is set to move the user to the second card in the HDML deck, with the name item2. On line 11, the other soft key, defined as soft1, links to another JSP called details.jsp, passing a parameter on the URL. The parameter name is product_id, and the value is defined using a JSP expression. Expressions are very good for embedding values within your markup language. In this example, we are using the expression <%= item1_id %> to set the value to 101, as defined earlier in the declaration on line 4. Once the actions for the card have been set, we output the data that will be seen on the device. For the first card, the data is Sony-TRV30 Digital Video Camcorder. In Figure 13.4, you can see the output of the first card on the Openwave HDML simulator. The JSP code and the resulting output for the second card (lines 14 to 18) and third card (lines 19 to 23) produce outputs similar to the first card.

Figure 13.4: Output from JSP shown in Listing 13.7.

The final card in the deck is different from the first three. In this card, rather than displaying static data, we use a JSP scriptlet to embed Java code that produces the output. In a JSP, you can embed blocks of Java code between the <% and %> tags (this is a scriptlet). This code is parsed by the server and executed as-is in the resulting servlet. In our example, the Java scriptlet starts on line 28 and ends on line 31. This code uses the request object to get a parameter called user from the URL. It then uses an out.println() statement to send a thank-you message to the user.

Being able to program in Java throughout your JSP is a powerful tool. In addition to accessing implicit objects available to the JSP, you can also communicate with external classes to access databases and other business logic. A word of caution is in order here: With the power that Java brings, some programmers go too far, and embed much more Java code than they should. Once you have more than a few lines of embedded Java code, you may want to consider using a JavaBeans component for your logic. The JavaBeans component contains Java logic in a defined format. The logic in this bean can be reused in other parts of this application or in entirely separate applications without additional programming. JSPs have prebuilt tags for accessing JavaBeans components. The syntax follows:

<jsp:useBean id="inventoryBean" class="sample.InventoryData" />

After the bean is defined using this syntax, you can then call methods in the bean directly from your JSP or Java code. In the same way it is possible to create your own JSP tags. Any time that a set of logic will be required in several JSP pages, it may be worthwhile to create a JSP tag library. Some of the wireless application vendors have taken this approach and have created JSP tag libraries for wireless application development. (Information on these vendors is available in Chapter 14.)

Other than their development methodologies, JavaServer Pages and Java servlets are nearly the same. The JSP specification extends the Java servlet API. Both are part of the J2EE specification, allowing them to easily interact with one another and with other J2EE technologies. Actually, at runtime, JSPs are compiled into Java servlets! The first time a JSP is requested, it is parsed into Java code, then compiled into a Java servlet. This servlet is then executed on the servlet engine, and will return the resulting content. Subsequent requests do not require a recompile, so the JSP simply is executed in the same manner as any other servlet. Figure 13.5 shows the logic that the server uses to determine whether a JSP has to be recompiled. When a request comes in, the server determines whether the JSP code has been changed since the last time it was executed. If it has been changed, the JSP is parsed into the Java source and compiled into a servlet, which is then executed. If the JSP source has not changed, the resulting servlet can be executed immediately. By using this process, the server ensures that any changes made to the JSP are displayed, without introducing a performance penalty for JSPs that have not changed.


Figure 13.5: Server logic used for JSPs.

Both JavaServer Pages and Java servlets provide everything you need to create interactive, dynamic, high-performance wireless Internet applications. They can be executed on a variety of platforms from Solaris to Linux to Windows, giving you the widest range of platform flexibility of any of the technologies discussed. In addition, J2EE technology has a large following among vendors and developers alike, providing many options for developing and deploying your wireless applications. Fortunately, you do have a choice between using a code-centric servlet approach or a page-centric JSP approach to development. Since they are both executed as servlets at runtime, the decision to use JSPs or servlets can be based upon development preferences.

Active Server Pages

Active Server Pages (ASPs) provide similar capabilities to those in JSPs. They combine a markup language and scripting and server components into a single file called an Active Server Page. ASPs are almost as efficient as writing ISAPI applications, and much more efficient than CGI applications. They run as a service in Microsoft's Internet Information Server (IIS) and support multithreaded environments.

ASP technology has been around longer than both Java servlets and JSPs. ASPs were first introduced by Microsoft in 1997 as the server-side execution environment in IIS for running ActiveX scripts and ActiveX server components. In practice, ASPs are most commonly used with either JScript, Microsoft's version of JavaScript, or Visual Basic, Scripting Edition (VBScript). Both of these scripting languages are supported natively, making them much more practical than ActiveX scripts. The model most commonly used with ASPs is Microsoft's Component Object Model (COM), although other component models are also supported.

When we look at the sample ASP in Listing 13.8, we see that the syntax of ASPs and JSPs is quite similar. This listing shows an ASP that generates the WML equivalent of the HDML code generated by the JSP in Listing 13.7. Most of the basic elements are the same. All of the code between the <% and %> delimiters is processed on the server. Everything else is sent to the client-side browser.

Listing 13.8: Active Server Page that outputs WML code.
Start example
1.  <% response.ContentType = "text/vnd.wap.wml" %>
2.  <%@ Language=VBScript %>
3.  <!-- variable declaration -->
4.  <% Item1_id="101" %>
5.  <% Item2_id="102" %>
6.  <% Item3_id="103" %>
7.  <?xml version="1.0" encoding=" UTF-8"?>
8.  <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
9.  <wml>
10.   <card id="item1">
11.     <do type="accept" label="next">
12.       <go href="#item2"/>
13.     </do>
14.     <do type="cancel" label="details">
15.       <go href=" details.asp?product_id=<%=Item1_id %>"/>
16.     </do>
17.     <p align="center"><b>Inventory Items</b></p>
18.     <p> Sony-TRV30 Digital Video Camcorder </p>
19.   </card>
20.   <card id="item2">
21.     <do type="accept" label="next">
22.       <go href="#item3"/>
23.     </do>
24.     <do type="cancel" label="details">
25.       <go href="details.asp?product_id=<%=Item2_id %>"/>
26.     </do>
27.     <p align="center"><b>Inventory Items</b></p>
28.     <p> Hitachi-VMD875L Digital 8 Camcorder </p>
29.   </card>
30.   <card id="item3">
31.     <do type="accept" label="next">
32.       <go href="#finish"/>
33.     </do>
34.     <do type="cancel" label="details">
35.       <go href="details.asp?product_id=<%=Item3_id %>"/>
36.     </do>
37.     <p align="center"><b>Inventory Items</b></p>
38.     <p> Sony-DCR-IP7BT Micro MV Network Handycam </p>
39.   </card>
40.   <card id="finish">
41.     <do type="accept" label="start over">
42.       <go href="#item1"/>
43.     </do>
44.     <!-- VBScript to get URL parameter -->
45.     <% userName = request.queryString("user") %>
46.     <p> Thank-you for visiting <%= userName %> </p>
47.   </card>
48. </wml>
End example

Line 1 specifies the content type using the response object. In this case, we specify the content type to be text/vnd.wap.wml since we are creating WAP content. The second line specifies the scripting language. This line is optional. If it is not present, VBScript is the default value. Lines 4 to 6 specify values for the three variables that we use later in the WML code. (Notice that with VBScript you do not have to define a data type for the variables.) After these initial lines of script, we are left with our WML template and embedded VBScript expressions for the remainder of the ASP, in lines 7 to 48.

This application works much like the HDML example did. There are four cards. The first three display inventory information; the fourth shows a personalized thankyou message. On lines 15, 25, and 35, we embed the product_id in the WML code, using VBScript. The VBScript has been directly incorporated into the markup language using the <%=variable_name%> syntax. These lines show an href to another ASP page, passing a parameter with the URL. Finally, in lines 45 and 46 we have VBScript that uses the request object to obtain the username from the URL parameter called user. Once the username is obtained, it is then displayed with a thank-you message to the user. This example shows how you can send and obtain information to and from the ASP page.

As for the technologies previously discussed, we have only touched the surface of what ASPs can do. This is even more true in regard to the latest version, ASP.NET. The following is the definition of ASP.NET as stated by Microsoft on the ASP.NET developer site:(http://msdn.microsoft.com/library/default.asp?url=/nhp/Default.asp?contentid=28000440)

  • ASP.NET (formerly referred to as ASP+) is more than the next version of Active Server Pages (ASP); it is a unified Web development platform that provides the services necessary for developers to build enterprise-class Web applications. While ASP.NET is largely syntax-compatible with ASP, it also provides a new programming model and infrastructure that enables a powerful new class of applications. You can augment your existing ASP applications by incrementally adding ASP.NET functionality to them.

Depending on your point of view, ASP technology is either very proprietary or very well integrated. It is a Microsoft technology that works great with other Microsoft technologies, as you would expect. As discussed, when creating an Active Server Page, you will use either VBScript or JScript as the scripting language, COM as the component model, and execute them in IIS, running on Microsoft server platforms. If you are currently using Microsoft technology for your development efforts, ASPs may be the ideal solution for creating your wireless Internet applications. If you do not typically use Microsoft technology, or use operating systems other than 32-bit Windows, you may want to look at the available Java technologies or an XML/XSL solution.

XML with XSL Stylesheets

The final approach that we will look at is converting eXtensible Markup Language (XML) data with eXtensible Stylesheet Language (XSL) stylesheets. This combination has generated much excitement in the industry due to its clean separation of data and presentation logic. Just as ASPs and JSPs improved on CGI and servlets in separating data from presentation, XML and XSL improve upon the ASP and JSP approach. Rather than using a page-based approach with embedded logic, XSL stylesheets can take raw XML data and format it to the desired markup language. This results in a separate XSL stylesheet for each markup language generated. For example, if you have one set of XML data that you want to present using XHTML, WML, and cHTML, you will end up with three separate XSL stylesheets for each page of generated content. If your application requires five decks for the WML application, and five pages for both the XHTML and cHTML applications, you would then require 15 XSL stylesheets to format the pages to the appropriate content. Essentially, each page you are developing requires its own XSL stylesheet.

We will go through an example of the entire process, starting with the XML document, then formatting it using an XSL stylesheet, and looking at the resulting WML code. Listing 13.9 is the XML document that contains the inventory data used for the application. It conforms to the XML syntax rules as discussed earlier in this chapter: All tags are case-sensitive; attribute values are enclosed in double quotes; all elements are properly nested; and all elements are well-formed. This is required for the XSL Transformation (XSLT) to take place.

Listing 13.9: XML Inventory Data
Start example
<?xml version="1.0"?>
<inventory>

  <product id="101">
    <name>
      <manufacturer>Sony</manufacturer>
      <model>TRV30</model>
    </name>
    <description>Digital Video Camcorder</description>
    <digitalstill>1360 x 1020</digitalstill>
    <format>Mini DV</format>
    <quantity>17</quantity>
    <price>1699.00</price>
  </product>

  <product id="102">
    <name>
      <manufacturer>Hitachi</manufacturer>
      <model>VMD875L</model>
    </name>
    <description>Digital 8 Camcorder</description>
    <format>Digital8</format>
    <quantity>24</quantity>
    <price>599.00</price>
  </product>

  <product id="103">
    <name>
      <manufacturer>Sony</manufacturer>
      <model>DCR-IP7BT</model>
    </name>
    <description>Micro MV Network Handycam</description>
    <digitalstill>640 x 480</digitalstill>
    <format>Micro MV</format>
    <quantity>11</quantity>
    <price>2199.99</price>
  </product>
<product id="104">
    <name>
      <manufacturer>JVC</manufacturer>
      <model>GR-DV2000</model>
    </name>
    <description>High-Band Digital Video Camcorder</description>
    <digitalstill>1600 x 1200</digitalstill>
    <format>Mini DV</format>
    <quantity>4</quantity>
    <price>1599.00</price>
  </product>

  <product id="105">
    <name>
      <manufacturer>Canon</manufacturer>
      <model>ES8200V</model>
    </name>
    <description>8 MM Camcorder</description>
    <format>HI8MM</format>
    <quantity>37</quantity>
    <price>399.00</price>
  </product>

</inventory>
End example

XML Document

Listing 13.9 contains a complete XML document. The XML document is text, and can be stored in a text file, a database, or any other storage mechanism. Or it may be assembled by some of the technologies we have discussed earlier in the chapter, including CGI, Java servlets, JSPs, or ASPs. In any case, it is stored and transmitted in a text format and can be edited and viewed with any standard text editor.

If you are trying to do more than simply view the XML document, you will require an XML parser. The parser will divide the document into individual pieces that can be passed back to the application. If the XML is not well formed, the parser will return an error. It will not attempt to fix the problem in the file. If you choose to, you can go one step beyond having well formed documents. If, say, you want to define a set of precise rules regarding what is valid for the XML document, you will want to use a Document Type Definition (DTD). The DTD either can be created for a specific purpose or be an existing DTD that is appropriate for the task. If you decide to use a DTD, it can either be included in the XML document itself or the XML document can point to a Universal Resource Identifier (URI) where it is located. In order to make sure the XML document adheres to the DTD, you will require a validating parser. These parsers will not only check to make sure the document is well formed, but will also make sure it is valid, as defined by the DTD.

Many applications include XML parsers. These include Web browsers, such as Internet Explorer and Netscape; word processors, such as StarOffice; and many development tools, including Sybase's PowerBuilder. Actually, since XML is such a flexible format for formatted data, anytime data is encoded as text; an XML document can be used to define the document structure.

In our example, the XML document is well formed, but no DTD is specified. The root element for this document is <inventory>. This is the only element in our document that does not have a parent element. It does, however, have one child element, <product>. Each <product> element then has six child elements: <name>, <description>, <digitalstill>, <format>, <quantity>, and <price>. Even though <product> has six children, each child only has one parent. If we go one layer deeper, the <name> element has two children: <manufacturer> and <model>. In addition, each product also has one attribute defined, the id. Data can be held in either child elements or in attributes. The decision is up to the designer of the XML document.

In our document we have five products with associated data. Each product does not necessarily have the same set of child elements. These vary depending on the product itself.

Note 

In order to create effective XSL stylesheets, it is a good idea to know the format of the XML data. We covered enough here to enable us to understand the XSLT process; this section does not address the full extent of the XML document structure.

XSL Stylesheet

Now that we understand the basic concepts about our XML document, we can examine how XSL stylesheets can be used to transform the data into various markup languages. There are many ways a stylesheet can be used to process XML data. One of the most common is to specify the stylesheet as line 1 of the XML document using the following syntax:

<?xml-stylesheet href="inventory.css" type="text/css"?>

This above syntax is often used with Cascading Style Sheets (CSS) that are processed by the Web browser. This is the method of transformation defined for the mobile profiles of XHTML. In our example, we are using an XSL stylesheet to do the transformation. XSL is the XML application that defines how one XML document is transformed into another. In our case, we will transform our XML data document into WML. In order for the translation to work, the XML document has to be well formed, but it does not necessarily have to be valid. Let's look at our XSL stylesheet in Listing 13.10.

Listing 13.10: XSL Stylesheet to convert XML from Listing 13.9 into WML.
Start example
1.  <?xml version="1.0"?>
2.  <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3.  <xsl:output method="xml" indent="yes" doctype-
system=" http://www.wapforum.org/DTD/wml_1.1.xml" doctype-public="-
//WAPFORUM//DTD WML 1.1//EN" />
4.  <xsl:template match="inventory">
5.  <wml>
6.    <card id="inventory">
7.      <p align="center">Inventory Items</p>
8.      <p>
9.        <select name="productId" multiple="false">
10.         <xsl:apply-templates select="product"/>
11.       </select>
12.     </p>
13.   </card>
14. </wml>
15. </xsl:template>
16. <xsl:template match="product">
17.     <xsl:variable name="product_id">
18.       <xsl:apply-templates select="@id" />
19.     </xsl:variable>
20.     <option value="{$product_id}">
21.       <xsl:apply-templates select="name"/>
22.       <onevent type="onpick">
23.         <go href="details.wml">
24.           <postfield name="product_id" value="{$product_id}"/>
25.         </go>
26.       </onevent>
27.    </option>
28. </xsl:template>
29. <xsl:template match="name">
30.     <xsl:value-of select="manufacturer"/>-<xsl:value-of
select="model"/>
31. </xsl:template>
32. </xsl:stylesheet>
End example

Line 1 is the XML declaration. This is not required, but is good to include. Line 2 of the stylesheet is the root element of the document. It has to be either a stylesheet, as we have used, or a transform. Either one is equally valid and means the same thing to an XSLT processor. For our example, we have used the Apache XML Project's Xalan XSLT processor.

A template-based methodology is used for the XML transformation. To match an output with an input, you define templates in your XSL stylesheet. The templates are defined by the <xsl:template> element, as shown in line 4. The element has a match attribute that uses XPath to identify the XML input it matches. When a corresponding input is found, the contents of the template are executed. On line 4 we have a template looking for a match on inventory. This happens to be the root element of our XML document, so there will be exactly one match in the XML document. The output of the match is the <wml> tag, along with a card with id="inventory". Within the card is a select element, which then applies the product template, as shown on line 10.

By using the <xsl:apply-templates> element, we can change the order in which the stylesheet is applied. By default, the XSLT processor goes from top to bottom. When it sees the <xsl:apply-templates> element, it will know which element to process next. In our example, we move from line 10 to the product template defined on line 16. The output from the product template will then be embedded into the code in the inventory template.

The first thing we do in the product template is set the variable named product_id, as shown on line 17. Line 18 defines the value to which we set the variable; it is retrieved from the id attribute within each product element of our XML document. After the variable is set, we add the item (as defined in the product element) to an <option> element. For the value shown for each option, we go to another template called name. This gets the <manufacturer> and <model> data. The code for this is shown on line 30. After the name template is applied, we then add the href with a postfield element, as shown on lines 23 and 24. This process will happen five times, because we have five matches for the product template, one for each product in our XML document.

Note 

Internet Explorer 5.0 and 5.5 include an XSLT processor, but do not support XSLT 1.0. When testing your applications, do not depend on IE to give you accurate output.

The resulting WML code from applying the XSL stylesheet to our XML document can be seen in Listing 13.11. The output on the Openwave simulator is shown in Figure 13.6. This figure has a complete WML deck containing a card with a select list. The list contains the five products from our XML code. For each product the manufacturer and model is shown. If a particular product is selected, another WML document called details.wml is called, and the product_id is passed as a parameter on the URL. This was accomplished using the postfield element. All of this WML code was generated automatically by the XSL stylesheet. If we wanted to generate code for another markup language, we would have to create another stylesheet similar to the one in Listing 13.10, but with specific tags for the markup language being targeted.


Figure 13.6: Openwave simulator showing the WML output from Listing 13.11.
Listing 13.11: Resulting WML code from XML in Listing 13.9 and XSL stylesheet in Listing 13.10.
Start example
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
  <card id="inventory">
    <p align="center">Inventory Items</p>
    <p>
      <select multiple="false" name="productId">
        <option value="101">Sony-TRV30
          <onevent type="onpick">
            <go href="details.wml">
              <postfield value="101" name="product_id"/>
            </go>
          </onevent>
        </option>
        <option value="102">Hitachi-VMD875L
          <onevent type="onpick">
            <go href="details.wml">
              <postfield value="102" name="product_id"/>
            </go>
          </onevent>
        </option>
        <option value="103">Sony-DCR-IP7BT
          <onevent type="onpick">
            <go href="details.wml">
              <postfield value="103" name="product_id"/>
            </go>
          </onevent>
        </option>
        <option value="104">JVC-GR-DV2000
          <onevent type="onpick">
            <go href=" details.wml">
              <postfield value="104" name="product_id"/>
            </go>
          </onevent>
        </option>
        <option value="105">Canon-ES8200V
          <onevent type="onpick">
            <go href="details.wml">
              <postfield value="105" name="product_id"/>
            </go>
          </onevent>
        </option>
      </select>
    </p>
  </card>
</wml>
End example

While the XML/XSL approach is ideal at a conceptual level, it does impose some problems during delivery. The first issue is the sheer number of XSL stylesheets that have to be created. You will require 15 stylesheets for a typical application with five separate screens/decks that target three markup languages. The resources required to develop and test these may be prohibitive. This limitation may be less significant in the future as many of the protocols move to XHTML as the markup language and as better tools come on the market for XSL creation; but at this point in time it is something to think about.

Even if you do decide that developing the required XSL stylesheets is worth the effort, you may still come across one other problem: performance. Each time a device makes a request, the XSLT processor has to transform the XML to the appropriate markup language. This is a resource-intensive process. Even with the caching mechanisms available, the performance penalty associated with this process may lead to problems for applications that will have a large number of simultaneous users.