March 19, 2011, 5:21 a.m.
posted by franni
Strategy for Using XML/XSL for Web Interfaces
XML and XSL can be used for many purposes. The primary purpose of XML is to represent data in a self-describing way. XML is not a programming or a logic-based language but one created to represent data with the metadata information included in the XML document. XSL is an XML-based language used by a transformer program (Apache Xalan-J, for example) to transform XML documents into other forms. When looking at XML and XSL, it is not obvious that these technologies can be used to build Web interfaces. However, using them together can greatly enhance separation of the presentation layer from the controller layer, as well as increase developer productivity.
The basic technique for creating Web interfaces using XML and XSL is to use a Java class to generate an XML stream, which can then be transformed into HTML using XSL. The domain objects and mediators use this XML Generator to generate a concise and complete XML document as output from some servlet request or Struts action. Figure shows how this technique fits into the MVC architecture.
In Figure, the interaction controller is responsible for obtaining the request and returning the HTML response. The interaction controller uses mediators and domain objects to service the request and then calls the XML Generator to generate the XML based on the data result returned from the domain model. Finally, the interaction controller calls the XSL Transformer to transform the XML into HTML as a response to the request.
Let's consider a set of requirements that we provide a Web interface for Time Sheet detailed data as well as Time Sheet Summary Information as shown in Figure.
1 Interaction Controller
The interaction controller is the gatekeeper to the function that is requested from a Web page URL. The interaction controller can be implemented as a servlet, a JSP, or as a Struts Action. The interaction controller has no logic in it except to process a request, delegate to other objects, and return a response.
2 XML Generator
The job of the XML Generator is to generate an XML DOM (Document Object Model), JDOM, or stream. While the generator could generate an XML document, rendering it in a persistent form is not necessary. The generated XML document will contain dynamic data, which is only valid for the duration of the request. Many implementations save the generated XML to a file for debugging purposes and turn this extra file output off when moving to production.
The structure of a generated XML document must represent what is needed for the Web interface rather than that of the domain model or data model. In a domain model, domain objects contain other domain objects. In a data model, foreign keys are used to relate multiple tables. In a Web interface, the data is derived from several domain objects and database tables. The generated XML document should contain preresolved relationships and references. The job of coding the XSL is a painting—not a programming—exercise, which we will cover shortly.
In order to create a Web interface, we need application data to drive the interface. The application data will almost always ultimately come from a database and the data it provides will be instantiated in some domain object. Consider a portion of the domain model for the time sheet case study (covered in its entirety later) in Figure.
We have a requirement to generate Web interfaces, which show the summary, detail, and combined information for a time sheet. We need data from each of the five domain objects pictured in Figure. However, it would not be prudent to generate an XML document from all the data contained in the domain model. The structure of a generated XML document must represent what is needed for the Web interface rather than that of the domain or data model.
The following XML document, timesheet.xml, gives us the needed data to meet the Web interface requirements for displaying a time sheet:
<?xml version="1.0" encoding="UTF-8"?> <TimeSheet weekEnding="4/25/2003"> <Employee id="257899" name="Leonard, Elouise" deptName="Programming"/> <Entries> <Entry> <Date>4/21/2003</Date> <Hours>8.5</Hours> <Project id="4567" name="ACME AP"/> </Entry> <Entry> <Date>4/22/2003</Date> <Hours>5</Hours> <Project id="4567" name="ACME AP"/> </Entry> <Entry> <Date>4/22/2003</Date> <Hours>5</Hours> <Project id="2345" name="ACME HR"/> </Entry> ... </Entries> <Summary totalHours="45.5" overTimeHours="5.5"> <ProjectTotals> <Project id="4567" name="ACME AP" totalHours="37.5"/> <Project id="2345" name="ACME HR" totalHours="8"/> </ProjectTotals> </Summary> </TimeSheet>
This XML document represents a time sheet for a single employee working on multiple projects. As you review the timesheet.xml file you will notice that the employee information as well as the detailed time sheet entries are included. Also, notice that Employee contains a deptName attribute instead of a subelement for Department with a name attribute. Since there is really no additional information needed from the Department besides its name, it is better to simplify the XML so that the XSL can be more easily coded. Additionally, notice that the XML document contains a summary element, which contains hourly totals by time sheet and project. This summary information could have been derived from the detailed information; however, it is a best practice to compute derived values in Java code, in the XML Generator, instead of in XSL. Java is a much more powerful language than XSL and therefore should be used to compute derived values.
XSL is essentially the paint for the Web interface. XSL is a combination of three other APIs:
XSLT supports conditional logic and looping constructs; however, the basic construction element in XSLT is the template, a block of XSLT code in many ways like a Java function. Templates can be named to act more like a function call or they can be set up to match an element in the XML data file.
XPath is the mechanism used in XSL to find elements and attributes in the XML data file. The XPath expression TimeSheet/Employee/@id gives a path from the current location in the XML document to the attribute id on the subelement Employee which is a part of the element TimeSheet. This is a very simple XPath expression but should show you right away that XSL was designed to make it very easy for programmers to find data in an XML document. XPath is used to locate things in an XML document. If we were to say that XML is like a database, we would also say that XPath is like SELECT in SQL.
XSL FO is an API and set of elements that allow an XSL developer to transform XML into other things besides XML, text, or HTML. XSL FO allows XML to be transformed into print streams and, even more importantly, PDF output.
In the previously provided XML document, we have an element named TimeSheet. As such, we can create a template in the XSL file, which matches TimeSheet. Listing 15.1 shows an XSL file, which contains a basic template to create summary time sheet information:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xalan="http://xml.apache.org/xslt"> <xsl:strip-space elements="*" /> <xsl:output method="html" /> <xsl:template match="TimeSheet"> <H1>Time Sheet</H1> <TABLE border="0"> <TR> <TD><B>Week Ending:</B></TD> <TD><xsl:value-of select="@weekEnding"/> </TD> <TD> </TD> <TD> </TD> </TR> <TR> <TD><B>Employee:</B></TD> <TD><xsl:value-of select="Employee/@name"/> </TD> <TD></TD> <TD><B>Total Hours:</B></TD> <TD><xsl:value-of select="Summary/@totalHours"/> </TD> </TR> <TR> <TD><B>Department:</B></TD> <TD><xsl:value-of select="Employee/@deptName"/> </TD> <TD> </TD> <TD><B>Total Overtime Hours:</B></TD> <TD> <xsl:value-of select="Summary/@overTimeHours"/> </TD> </TR> </TABLE> </xsl:template> </xsl:stylesheet>
This XSL file, timesheet1.xsl, contains a single template for the TimeSheet element. This XSL file is almost 90 percent HTML with the few XSL statements in bold typeface. With exception to the first five and the last two lines in Listing 15.1, the XSL statements are concerned with obtaining the data from the XML document. For example, the line
<TD><xsl:value-of select="@weekEnding"/> </TD>
will cause the value of the weekEnding attribute of the TimeSheet element to be placed inside the HTML TD element. Notice that the XPath expression "@weekEnding" is used to access the "weekEnding" attribute of the current element (TimeSheet). Also, the line
<TD><xsl:value-of select="Employee/@deptName"/> </TD>
will cause the value of the deptName attribute of the Employee element of the TimeSheet element to be placed inside of the HTML TD element.
When the timesheet1.xsl file is applied to the timesheet.xml file, the result will resemble Figure.
4 Pulling It All Together
Figure represents a portion of the time sheet output that we would like to build in XML and XSL. We will add additional templates and expressions to the XSL so that we obtain the Web interface shown in Figure. We will not have to change the XML document as it contains all of the necessary data. For now, it is important to understand that while we are using a static XML document in this discussion so far, in our completed application the XML Generator will generate an XML stream with dynamic data and then it will be transformed with our XSL.