[This local archive copy is from the official and canonical URL, http://java.apache.org/cocoon/xsp/WD-xsp.html; please refer to the canonical source document if possible.]
|
This document specifies both an XML document type defintion and a development methodology to generate dynamic XML by server side processing of client's requests. Such a specification is useful to define an open and standard way to develop and maintain dynamic XML server pages. The technology described in this document was designed to complete the XML-based publishing framework defined by the Cocoon Project and it's mainly targetted on this project, even if the final goal of this effort is to submit a request to a standard body (such as W3C) for final recomandation.
The need for an open language to standardizing server side programmatic XML generation was observed when XML-based web publishing frameworks emerged and no available technology was detailed, stable, useful and open enough to be used. XSP, by mixing Turing-complete programming logic with page content, provide a flexible yet fully portable and extensible way to develop dynamic XML content. Moreover, being completely XML-based, XSP are fully integrated with XML-based web architectures that allow XSL-transformation to obtain the context separation that is needed for complex sites to increase their management parallelism.
Being based on an XML paradigm from the beginning, XSp don't suffer limitations other server pages technologies do: the ability to XSL-transform XSP directly and recursively allows a more compact and precise DTD to be designed since content/logic/style separation is performed by the architecture and not by the language itself. For this reason, XSP are completely transparent to the namespaces/document-types used.
Being a rather complex technology, the XSP specification will be separated into layers. These layers will have different goals and restrictions and will allow faster development cycles and a better defined development model. Every layer will define its own document type definition which may extend the one of the previous layer or completely change it, depending on layer goals. Layers should be seen as levels of abstraction, much like programming languages range from higher-level to low-level
Following is a summary of the design principles governing the general XSP specification:
- should integrate completely with existing W3C recomendations and working drafts
- should be programming language indipendent
- should be aimed to programmers but should be relatively easy to understand
- should allow pages to be compiled (into Java servlets or other equivalent technology)
- should not aim to replace existing technologies
- should be document oriented
- should allow easy reusability of page code
- should allow complete separation of knowledge contexts (content, logic and style)
- should be transparent to all but page programmers
- specification should be open to all but controlled directly by the Java Apache project
Following is a summary of the design principles governing the Layer 1 of the XSP specification:
- should define the complete element set
- should be aimed to machine generations so:
- reducing the number of elements to a minimum is of maximal importance
- verbosity of the generated documents is of minimal importance
- should be human readable/editable so:
- terseness and readability are of maximal importance
- indenting and formattation are of maximal importance
- should be possibly XSLT transformed directly into programming language source code
- should define the relations to the programming languages (object models, variable scopes)
Following is a summary of the design principles governing the Layer 2 of the XSP specification:
- should define a human oriented element set
- should be aimed to human generations so:
- reducing the number of elements to a minimum is of minimal importance
- reducing verbosity of the documents is of maximal importance
- should be aimed to medium-low knowledged programmers:
- automatization of complex operations is of maximal importance
- tendency to hide page logic is of maximal importance
- should be possibly XSLT transformed into XSP Layer 1 documents
The XSP specification would eventually evolve into a single specification with a single document type definition. This will happen when the working draft phase will be terminated and all involved parties will agree on the specification stability. The Layer 1 will be the first to be developed and tested in a working implementation. Subsequent layers will probably need several evolution stages to reach their final shape.
Three standards have been especially influential:
- JSP - Defines a way to embed programmatic logic into HTML documents (as well as XML documents from version 1.0).
- XSLT - Defines a way to transform XML documents.
- XML - Defines a flexible still highly structured paradigm for web content generation and distribution.
Many server side dynamic web content generators have been evaluated and confronted, expecially WebMacro and GSP.
The following basic terms apply in this document:
- document
- a document is the final result of the client request phase and they can be obtain from a single file that is read from disk/cache or by processing several ones. Documents are said static if their content doesn't change with user request parameters nor time. Documens are said dynamic if they do.
- page
- a page is the entity that is requested by the client and drives the document creation process. In the simplest case, a document is created reading the page and sending it directly without further processing. In case of compiled pages, a binary object is executed and it's content is used as page content. Pages are said compiled if they are translated into binary code. Note that compiled pages may be created from normal pages the first time the page is requested and executed as binary code in further requests for performance reasons.
- sheet
- a sheet is the processing unit of the document creation chain. Each sheet is a file and they contain the instructions to transform the requested page into the document sent to the requesting client. Sheets are said style sheets if they are the last of the chain and no further processing in performed, logic sheets if they contain XSP elements. Both types are said transformation sheets since they contain XSLT elements.
- document type
- a document type is a unique name that identifies the type of the document being generated. This term has the same meaning as in the XML specification. Note how a document has only one document type but this could change during processing since transformation sheets allow the transformation from one document type into another.
The XSP specification defines some external entities that may be used to reduce the verbosity of XSP document, allowing the inclusion the default DTD via entity mapping. The standard way to include the XSP DTD into XSP documents is:
<!DOCTYPE XSP SYSTEM "http://java.apache.org/cocoon/xsp/WD-xsp" "-//Java Apache//DTD XSP Layer 1//EN">
The XSP DTD was designed with simplicity in mind. The number of elements and attributes was reduced to a minimum to allow a fast and easy learning process. On the other hand, no special helper elements were defined in Layer 1 to reduce the spec development time and to favor early feedback from both implementors and users.
The following is the complete DTD. It must be noted that this DTD can hardly be used (alone) to validate any XSP due to the fact that XSP are namespace orthogonal and are designed to include as content mark-up elements that belong to other namespaces.
<!ELEMENT xsp:page (xsp:structure?, xsp:logic?, xsp:content)> <!ATTLIST xsp:page language CDATA #REQUIRED result-ns NMTOKEN #IMPLIED default-space (preserve|strip) "preserve" indent-result (yes|no) "no" xmlns:xsp CDATA #FIXED "http://java.apache.org/cocoon/xsp" xml:space (default|preserve) "preserve" > <!ELEMENT xsp:structure (xsp:dtd?, xsp:include*)> <!ELEMENT xsp:dtd (#PCDATA)> <!ELEMENT xsp:include (#PCDATA)> <!ELEMENT xsp:variable (#PCDATA)><!ELEMENT xsp:content (#PCDATA | xsp:logic | xsp:element | xsp:eval | xsp:pi | xsp:comment)* > <!ELEMENT xsp:logic (#PCDATA | xsp:eval | xsp:content | xsp:element | xsp:comment | xsp:pi)* > <!ATTLIST xsp:logic xml:space (default|preserve) "preserve" > <!ELEMENT xsp:element (#PCDATA | xsp:attribute | xsp:element | xsp:logic)* > <!ATTLIST xsp:element name CDATA #REQUIRED > <!ELEMENT xsp:attribute (#PCDATA)> <!ATTLIST xsp:attribute name CDATA #REQUIRED xml:space (default|preserve) "preserve" > <!ELEMENT xsp:pi (#PCDATA | xsp:eval> <!ELEMENT xsp:comment (#PCDATA | xsp:eval)> <!ELEMENT xsp:eval (#PCDATA)>
Consider the following XML source document:
<?xml version="1.0"?> <!DOCTYPE page> <page> <title>A Sample XSP Page</title> <p>Hi, I've been hit <counter/> times.</p> </page>
This simple example shows the power of content/logic/style separation. While the
<title>
tag has a very special meaning in the page document type, indicating the page title, the<counter>
element is needs to be dynamically substituted by the number of times the document has been requested. The logic that peforms such behavior is included in tag itself, but unlike other existing server side technologies, the behavior is not defined in the page itself, but on the logic sheet that is applied to evaluate this behavior. In fact, the same page may have a totally different behavior depending on the logicsheet that is applied to the page. Note that it's beyond the scope of this specification to define a way to associate transformation sheets to pages. The associated logicsheet that uses Java language as logic definition may look like:<?xml version="1.0"?> <xsl:transformation xmlns:xsl="http://www.w3.org/TR/WD-xsl" xmlns:xsp="http://java.apache.org/DTD/WD-xsp" result-ns="http://java.apache.org/DTD/WD-xsp" > <xsl:template match="page"> <xsp:page xmlns:xsp="http://java.apache.org/DTD/WD-xsp" language="java"> <xsp:structure> <xsp:include>java.lang.*</xsp:include> </xsp:structure> <xsp:logic> private static int counter = 0; private synchronized int currentCount() { return ++counter; } </xsp:logic> <xsp:content> <page> <xsl:apply-templates/> </page> </xsp:content> </xsp:page> </xsl:template> <xsl:template match="counter"> <xsp:eval>currentCount()</xsp:eval> </xsl:template> <!-- Transcribe everything else verbatim --> <xsl:template match="*|@*|comment()|pi()|text()"> <xsl:copy> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>After applying the above logic sheet, the resulting DOM tree would be equivalent to the following XSP document:
<xsp:page xmlns:xsp="http://java.apache.org/DTD/WD-xsp" result-ns="http://www.dummy.org/SimpleHomepageDTD" language="java"> <xsp:structure> <xsp:include>java.lang.*</xsp:include> </xsp:structure> <xsp:logic> private static int counter = 0; private synchronized int currentCount() { return ++counter; } </xsp:logic> <xsp:content> <page> <title>A Sample XSP Page</title> <p>Hi, I've been hit <xsp:eval>currentCount()</xsp:eval> times.</p> </page> </xsp:content> </xsp:page>At this point it's worth to note that from an XSP point of view, there is no difference in how the XSP page was created, either directly written or created with n levels of transformation. So, independently of whether an XSL stylesheet or a special algorithm was used to generate the final source code, it may look like this (many key issues regarding servlets were omitted for simplicity and this example must not be considered mandating as a way to format XSP into servlet source code):
// package automatically created from the full request URL... package org.apache.cocoon.xsp.example;// packages imported automatically by source code generator import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import org.w3c.dom.*; // packages imported due to XSP structure import java.lang.*; // class name automatically created from the request URI file name... public class Counter extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); } private static int counter = 0; private synchronized int currentCount() { return ++counter; } public void service(HttpServletRequest request, HttpServletResponse response) throws IOException { PrintWriter out = response.getWriter(); BufferedReader in = request.getReader(); try { Document document = parser.createEmptyDocument(); Element root = document.createElement("page"); document.appendChild(root); Element element_1 = document.createElement("title"); root.appendChild(element_1); Text textNode_1 = document.createTextNode("A Sample XSP Page"); element_1.appendChild(textNode_1); Element element_2 = document.createElement("p"); root.appendChild(element_2); Text textNode_2 = document.createTextNode("Hi, I've been hit "); element_2.appendChild(textNode_2); Text textNode_3 = document.createTextNode((new StringBuffer.append(currentCount())).toString()); element_2.appendChild(textNode_3); Text textNode_4 = document.createTextNode("times."); element_2.appendChild(textNode_4); // Produce generated DOM tree on output as an XML stream ((Child) document).toXMLString(out); } catch (Exception e) { out.println("<!-- Error: " + e.getMessage() + " -->"); } } }Note that in this example the XML document is being generated as a stream rather than as a DOM tree. This is so because the current servlet specification does not allow for content generation in a format other than a stream. A rather undesirable consequence of this is that the resulting XML document would need to be re-parsed in case a final XSL stylesheet or other post-transformation must be applied.
An open issue is whether XSP servlets should extend the HttpServlet interfaces to add specialized DOM variants of the request and response objects as well as the service method. Under this assumption, the extended HttpServlet interface would be:
public interface DOMServlet extends HttpServlet { public Document service(DOMRequest request, DOMResponse response); }This is still subject to debate because extending the standard Java servlet interfaces by adding a specialized service method would also imply developing a specialized servlet engine. Nevertheless, the ability to generate DOM trees (in addition to streams) is central to XSP as it should be used both in a servlet environment and in Java applications providing batch tree construction capabilities.
Anyway, it is beyond the scope of this specification to define how XSP are translated into binary code and how these interact with the publishing frameworks that handle them.
The following have contributed to authoring this draft:
Ricardo Rocha <rrocha@plenix.org>