| <HTML><HEAD><SCRIPT language="JavaScript" src="resources/script.js" type="text/javascript"></SCRIPT><TITLE>XSLTC runtime environment</TITLE></HEAD><BODY alink="#ff0000" bgcolor="#ffffff" leftmargin="4" link="#0000ff" marginheight="4" marginwidth="4" text="#000000" topmargin="4" vlink="#0000aa"><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD align="left" height="60" rowspan="3" valign="top" width="135"><IMG alt="logo" border="0" height="60" hspace="0" src="resources/logo.gif" vspace="0" width="135"></TD><TD align="left" colspan="4" height="5" valign="top" width="456"><IMG alt="line" border="0" height="5" hspace="0" src="resources/line.gif" vspace="0" width="456"></TD><TD align="left" height="60" rowspan="3" valign="top" width="29"><IMG alt="right" border="0" height="60" hspace="0" src="resources/right.gif" vspace="0" width="29"></TD></TR><TR><TD align="left" bgcolor="#0086b2" colspan="4" height="35" valign="top" width="456"><IMG alt="" border="0" height="35" hspace="0" src="graphics/xsltc_runtime-header.jpg" vspace="0" width="456"></TD></TR><TR><TD align="left" height="20" valign="top" width="168"><IMG alt="bottom" border="0" height="20" hspace="0" src="resources/bottom.gif" vspace="0" width="168"></TD><TD align="left" height="20" valign="top" width="96"><A href="http://xml.apache.org/" onMouseOut="rolloverOff('xml');" onMouseOver="rolloverOn('xml');" target="new"><IMG alt="http://xml.apache.org/" border="0" height="20" hspace="0" name="xml" onLoad="rolloverLoad('xml','resources/button-xml-hi.gif','resources/button-xml-lo.gif');" src="resources/button-xml-lo.gif" vspace="0" width="96"></A></TD><TD align="left" height="20" valign="top" width="96"><A href="http://www.apache.org/" onMouseOut="rolloverOff('asf');" onMouseOver="rolloverOn('asf');" target="new"><IMG alt="http://www.apache.org/" border="0" height="20" hspace="0" name="asf" onLoad="rolloverLoad('asf','resources/button-asf-hi.gif','resources/button-asf-lo.gif');" src="resources/button-asf-lo.gif" vspace="0" width="96"></A></TD><TD align="left" height="20" valign="top" width="96"><A href="http://www.w3.org/" onMouseOut="rolloverOff('w3c');" onMouseOver="rolloverOn('w3c');" target="new"><IMG alt="http://www.w3.org/" border="0" height="20" hspace="0" name="w3c" onLoad="rolloverLoad('w3c','resources/button-w3c-hi.gif','resources/button-w3c-lo.gif');" src="resources/button-w3c-lo.gif" vspace="0" width="96"></A></TD></TR></TABLE><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD align="left" valign="top" width="120"><IMG alt="join" border="0" height="14" hspace="0" src="resources/join.gif" vspace="0" width="120"><BR> |
| |
| <A href="index.html" onMouseOut="rolloverOff('side-index');" onMouseOver="rolloverOn('side-index');"><IMG alt="Overview" border="0" height="12" hspace="0" name="side-index" onLoad="rolloverLoad('side-index','graphics/index-label-2.jpg','graphics/index-label-3.jpg');" src="graphics/index-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="xsltc_compiler.html" onMouseOut="rolloverOff('side-xsltc_compiler');" onMouseOver="rolloverOn('side-xsltc_compiler');"><IMG alt="Compiler design" border="0" height="12" hspace="0" name="side-xsltc_compiler" onLoad="rolloverLoad('side-xsltc_compiler','graphics/xsltc_compiler-label-2.jpg','graphics/xsltc_compiler-label-3.jpg');" src="graphics/xsltc_compiler-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="xsl_whitespace_design.html" onMouseOut="rolloverOff('side-xsl_whitespace_design');" onMouseOver="rolloverOn('side-xsl_whitespace_design');"><IMG alt="Whitespace" border="0" height="12" hspace="0" name="side-xsl_whitespace_design" onLoad="rolloverLoad('side-xsl_whitespace_design','graphics/xsl_whitespace_design-label-2.jpg','graphics/xsl_whitespace_design-label-3.jpg');" src="graphics/xsl_whitespace_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="xsl_sort_design.html" onMouseOut="rolloverOff('side-xsl_sort_design');" onMouseOver="rolloverOn('side-xsl_sort_design');"><IMG alt="xsl:sort" border="0" height="12" hspace="0" name="side-xsl_sort_design" onLoad="rolloverLoad('side-xsl_sort_design','graphics/xsl_sort_design-label-2.jpg','graphics/xsl_sort_design-label-3.jpg');" src="graphics/xsl_sort_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="xsl_key_design.html" onMouseOut="rolloverOff('side-xsl_key_design');" onMouseOver="rolloverOn('side-xsl_key_design');"><IMG alt="Keys" border="0" height="12" hspace="0" name="side-xsl_key_design" onLoad="rolloverLoad('side-xsl_key_design','graphics/xsl_key_design-label-2.jpg','graphics/xsl_key_design-label-3.jpg');" src="graphics/xsl_key_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="xsl_comment_design.html" onMouseOut="rolloverOff('side-xsl_comment_design');" onMouseOver="rolloverOn('side-xsl_comment_design');"><IMG alt="Comment design" border="0" height="12" hspace="0" name="side-xsl_comment_design" onLoad="rolloverLoad('side-xsl_comment_design','graphics/xsl_comment_design-label-2.jpg','graphics/xsl_comment_design-label-3.jpg');" src="graphics/xsl_comment_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="xsl_lang_design.html" onMouseOut="rolloverOff('side-xsl_lang_design');" onMouseOver="rolloverOn('side-xsl_lang_design');"><IMG alt="lang()" border="0" height="12" hspace="0" name="side-xsl_lang_design" onLoad="rolloverLoad('side-xsl_lang_design','graphics/xsl_lang_design-label-2.jpg','graphics/xsl_lang_design-label-3.jpg');" src="graphics/xsl_lang_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="xsl_unparsed_design.html" onMouseOut="rolloverOff('side-xsl_unparsed_design');" onMouseOver="rolloverOn('side-xsl_unparsed_design');"><IMG alt="Unparsed entities" border="0" height="12" hspace="0" name="side-xsl_unparsed_design" onLoad="rolloverLoad('side-xsl_unparsed_design','graphics/xsl_unparsed_design-label-2.jpg','graphics/xsl_unparsed_design-label-3.jpg');" src="graphics/xsl_unparsed_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| <A href="xsl_if_design.html" onMouseOut="rolloverOff('side-xsl_if_design');" onMouseOver="rolloverOn('side-xsl_if_design');"><IMG alt="If design" border="0" height="12" hspace="0" name="side-xsl_if_design" onLoad="rolloverLoad('side-xsl_if_design','graphics/xsl_if_design-label-2.jpg','graphics/xsl_if_design-label-3.jpg');" src="graphics/xsl_if_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsl_choose_design.html" onMouseOut="rolloverOff('side-xsl_choose_design');" onMouseOver="rolloverOn('side-xsl_choose_design');"><IMG alt="Choose|When|Otherwise design" border="0" height="12" hspace="0" name="side-xsl_choose_design" onLoad="rolloverLoad('side-xsl_choose_design','graphics/xsl_choose_design-label-2.jpg','graphics/xsl_choose_design-label-3.jpg');" src="graphics/xsl_choose_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsl_include_design.html" onMouseOut="rolloverOff('side-xsl_include_design');" onMouseOver="rolloverOn('side-xsl_include_design');"><IMG alt="Include|Import design" border="0" height="12" hspace="0" name="side-xsl_include_design" onLoad="rolloverLoad('side-xsl_include_design','graphics/xsl_include_design-label-2.jpg','graphics/xsl_include_design-label-3.jpg');" src="graphics/xsl_include_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsl_variable_design.html" onMouseOut="rolloverOff('side-xsl_variable_design');" onMouseOver="rolloverOn('side-xsl_variable_design');"><IMG alt="Variable|Param design" border="0" height="12" hspace="0" name="side-xsl_variable_design" onLoad="rolloverLoad('side-xsl_variable_design','graphics/xsl_variable_design-label-2.jpg','graphics/xsl_variable_design-label-3.jpg');" src="graphics/xsl_variable_design-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <IMG alt="Runtime" border="0" height="12" hspace="0" src="graphics/xsltc_runtime-label-1.jpg" vspace="0" width="120"><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="xsltc_dom.html" onMouseOut="rolloverOff('side-xsltc_dom');" onMouseOver="rolloverOn('side-xsltc_dom');"><IMG alt="Internal DOM" border="0" height="12" hspace="0" name="side-xsltc_dom" onLoad="rolloverLoad('side-xsltc_dom','graphics/xsltc_dom-label-2.jpg','graphics/xsltc_dom-label-3.jpg');" src="graphics/xsltc_dom-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="xsltc_namespace.html" onMouseOut="rolloverOff('side-xsltc_namespace');" onMouseOver="rolloverOn('side-xsltc_namespace');"><IMG alt="Namespaces" border="0" height="12" hspace="0" name="side-xsltc_namespace" onLoad="rolloverLoad('side-xsltc_namespace','graphics/xsltc_namespace-label-2.jpg','graphics/xsltc_namespace-label-3.jpg');" src="graphics/xsltc_namespace-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="xsltc_trax.html" onMouseOut="rolloverOff('side-xsltc_trax');" onMouseOver="rolloverOn('side-xsltc_trax');"><IMG alt="Translet & TrAX" border="0" height="12" hspace="0" name="side-xsltc_trax" onLoad="rolloverLoad('side-xsltc_trax','graphics/xsltc_trax-label-2.jpg','graphics/xsltc_trax-label-3.jpg');" src="graphics/xsltc_trax-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsltc_predicates.html" onMouseOut="rolloverOff('side-xsltc_predicates');" onMouseOver="rolloverOn('side-xsltc_predicates');"><IMG alt="XPath Predicates" border="0" height="12" hspace="0" name="side-xsltc_predicates" onLoad="rolloverLoad('side-xsltc_predicates','graphics/xsltc_predicates-label-2.jpg','graphics/xsltc_predicates-label-3.jpg');" src="graphics/xsltc_predicates-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsltc_iterators.html" onMouseOut="rolloverOff('side-xsltc_iterators');" onMouseOver="rolloverOn('side-xsltc_iterators');"><IMG alt="Xsltc Iterators" border="0" height="12" hspace="0" name="side-xsltc_iterators" onLoad="rolloverLoad('side-xsltc_iterators','graphics/xsltc_iterators-label-2.jpg','graphics/xsltc_iterators-label-3.jpg');" src="graphics/xsltc_iterators-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsltc_native_api.html" onMouseOut="rolloverOff('side-xsltc_native_api');" onMouseOver="rolloverOn('side-xsltc_native_api');"><IMG alt="Xsltc Native API" border="0" height="12" hspace="0" name="side-xsltc_native_api" onLoad="rolloverLoad('side-xsltc_native_api','graphics/xsltc_native_api-label-2.jpg','graphics/xsltc_native_api-label-3.jpg');" src="graphics/xsltc_native_api-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsltc_trax_api.html" onMouseOut="rolloverOff('side-xsltc_trax_api');" onMouseOver="rolloverOn('side-xsltc_trax_api');"><IMG alt="Xsltc TrAX API" border="0" height="12" hspace="0" name="side-xsltc_trax_api" onLoad="rolloverLoad('side-xsltc_trax_api','graphics/xsltc_trax_api-label-2.jpg','graphics/xsltc_trax_api-label-3.jpg');" src="graphics/xsltc_trax_api-label-3.jpg" vspace="0" width="120"></A><BR> |
| <A href="xsltc_performance.html" onMouseOut="rolloverOff('side-xsltc_performance');" onMouseOver="rolloverOn('side-xsltc_performance');"><IMG alt="Performance Hints" border="0" height="12" hspace="0" name="side-xsltc_performance" onLoad="rolloverLoad('side-xsltc_performance','graphics/xsltc_performance-label-2.jpg','graphics/xsltc_performance-label-3.jpg');" src="graphics/xsltc_performance-label-3.jpg" vspace="0" width="120"></A><BR> |
| <IMG alt="close" border="0" height="14" hspace="0" src="resources/close.gif" vspace="0" width="120"><BR></TD><TD align="left" valign="top" width="500"><TABLE border="0" cellpadding="3" cellspacing="0"><TR><TD> |
| |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Contents</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>This document describes the design and overall architecture of XSLTC's |
| runtime environment. This does not include the internal DOM and the DOM |
| iterators, which are all covered in separate documents.</P> |
| |
| <UL> |
| <LI><A href="#overview">Runtime overview</A></LI> |
| <LI><A href="#translet">The compiled translet</A></LI> |
| <LI><A href="#types">External/internal type mapping</A></LI> |
| <LI><A href="#mainloop">Main program loop</A></LI> |
| <LI><A href="#library">Runtime library</A></LI> |
| <LI><A href="#output">Output handling</A></LI> |
| </UL> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| |
| |
| <A name="overview"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Runtime overview</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>This figure shows the main components of XSLTC's runtime environment:</P> |
| |
| <P><IMG align="right" alt="runtime_design.gif" border="0" hspace="4" src="images/runtime_design.gif" vspace="4"><BR clear="all"></P> |
| <P><I>Figure 1: Runtime environment overview</I></P> |
| |
| <P>The various steps these components have to go through to transform a |
| document are:</P> |
| |
| <UL> |
| <LI>instanciate a parser and hand it the input document</LI> |
| <LI>build an internal DOM from the parser's SAX events</LI> |
| <LI>instanciate the translet object</LI> |
| <LI>pass control to the translet object</LI> |
| <LI>receive output events from the translet</LI> |
| <LI>format the output document</LI> |
| </UL> |
| |
| <P>This process can be initiated either through XSLTC's native API or |
| through the implementation of the JAXP/TrAX API.</P> |
| |
| </FONT></TD></TR></TABLE><BR><A name="translet"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>The compiled translet</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>A translet is always a subclass of <CODE><FONT face="courier, monospaced">AbstractTranslet</FONT></CODE>. As well |
| as having access to the public/protected methods in this class, the |
| translet is compiled with these methods:</P><DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public void transform(DOM, NodeIterator, TransletOutputHandler);</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This method is passed a <CODE><FONT face="courier, monospaced">DOMImpl</FONT></CODE> object. Depending on whether |
| the stylesheet had any calls to the <CODE><FONT face="courier, monospaced">document()</FONT></CODE> function this |
| method will either generate a <CODE><FONT face="courier, monospaced">DOMAdapter</FONT></CODE> object (when only one |
| XML document is used as input) or a <CODE><FONT face="courier, monospaced">MultiDOM</FONT></CODE> object (when there |
| are more than one XML input documents). This DOM object is passed on to |
| the <CODE><FONT face="courier, monospaced">topLevel()</FONT></CODE> method.</P> |
| |
| <P>When the <CODE><FONT face="courier, monospaced">topLevel()</FONT></CODE> method returns, we initiate the output |
| document by calling <CODE><FONT face="courier, monospaced">startDocument()</FONT></CODE> on the supplied output |
| handler object. We then call <CODE><FONT face="courier, monospaced">applyTemplates()</FONT></CODE> to get the actual |
| output contents, before we close the output document by calling |
| <CODE><FONT face="courier, monospaced">endDocument()</FONT></CODE> on the output handler.</P><DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public void topLevel(DOM, NodeIterator, TransletOutputHandler);</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This method handles all of these top-level elements:</P> |
| <UL> |
| <LI><CODE><FONT face="courier, monospaced"><xsl:output></FONT></CODE></LI> |
| <LI><CODE><FONT face="courier, monospaced"><xsl:decimal-format></FONT></CODE></LI> |
| <LI><CODE><FONT face="courier, monospaced"><xsl:key></FONT></CODE></LI> |
| <LI><CODE><FONT face="courier, monospaced"><xsl:param></FONT></CODE> (for global parameters)</LI> |
| <LI><CODE><FONT face="courier, monospaced"><xsl:variable></FONT></CODE> (for global variables)</LI> |
| </UL><DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public void applyTemplates(DOM, NodeIterator, TransletOutputHandler);</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This is the method that produces the actual output. Its central element |
| is a big <CODE><FONT face="courier, monospaced">switch()</FONT></CODE> statement that is used to trigger the code |
| that represent the available templates for the various node in the input |
| document. See the chapter on the |
| <A href="#mainloop">main program loop</A> for details on this method. |
| </P><DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public void <init>();</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <A name="namesarray"><!--anchor--></A> |
| <P>The translet's constructor initializes a table of all the elements we |
| want to search for in the XML input document. This table is called the |
| <CODE><FONT face="courier, monospaced">namesArray</FONT></CODE>, and maps each element name to an unique integer |
| value, know as the elements "translet-type". |
| The DOMAdapter, which acts as a mediator between the DOM and the translet, |
| will map these element identifier to the element identifiers used internally |
| in the DOM. See the section on <A href="#types">extern/internal type |
| mapping</A> and the internal DOM design document for details on this.</P> |
| |
| <P>The constructor also initializes any <CODE><FONT face="courier, monospaced">DecimalFormatSymbol</FONT></CODE> |
| objects that are used to format numbers before passing them to the |
| output post-processor. The output processor uses thes symbols to format |
| decimal numbers in the output.</P><DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public boolean stripSpace(int nodeType);</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This method is only present if any <CODE><FONT face="courier, monospaced"><xsl:strip-space></FONT></CODE> |
| or <CODE><FONT face="courier, monospaced"><xsl:preserve-space></FONT></CODE> elements are present in the |
| stylesheet. If that is the case, the translet implements the |
| <CODE><FONT face="courier, monospaced">StripWhitespaceFilter</FONT></CODE> interface by containing this method.</P> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| |
| |
| <A name="types"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>External/internal type mapping</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>This is the very core of XSL transformations: |
| <B>Read carefully!!!</B></P> |
| |
| <A name="external-types"><!--anchor--></A> |
| <P>Every node in the input XML document(s) is assigned a type by the DOM |
| builder class. This type is a unique integer value which represents the |
| element, so that for instance all <CODE><FONT face="courier, monospaced"><bob></FONT></CODE> elements in the |
| input document will be given type <CODE><FONT face="courier, monospaced">7</FONT></CODE> and can be referred to by |
| that integer. These types can be used for lookups in the |
| <A href="#namesarray">namesArray</A> table to get the actual |
| element name (in this case "bob"). The type identifiers used in the DOM are |
| referred to as <B>external types</B> or <B>DOM types</B>, as they are |
| types known only outside of the translet.</P> |
| |
| <A name="internal-types"><!--anchor--></A> |
| <P>Similarly the translet assignes types to all element and attribute names |
| that are referenced in the stylesheet. This type assignment is done at |
| compile-time, while the DOM builder assigns the external types at runtime. |
| The element type identifiers used by the translet are referred to as |
| <B>internal types</B> or <B>translet types</B>.</P> |
| |
| <P>It is not very probable that there will be a one-to-one mapping between |
| internal and external types. There will most often be elements in the DOM |
| (ie. the input document) that are not mentioned in the stylesheet, and |
| there could be elements in the stylesheet that do not match any elements |
| in the DOM. Here is an example:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| <?xml version="1.0"?> |
| <xsl:stylesheet version="1.0" xmlns:xsl="blahblahblah"> |
| |
| <xsl:template match="/"> |
| <xsl:for-each select="//B"> |
| <xsl:apply-templates select="." /> |
| </xsl:for-each> |
| <xsl:for-each select="C"> |
| <xsl:apply-templates select="." /> |
| </xsl:for-each> |
| <xsl:for-each select="A/B"> |
| <xsl:apply-templates select="." /> |
| </xsl:for-each> |
| </xsl:template> |
| |
| </xsl:stylesheet> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>In this stylesheet we are looking for elements <CODE><FONT face="courier, monospaced"><B></FONT></CODE>, |
| <CODE><FONT face="courier, monospaced"><C></FONT></CODE> and <CODE><FONT face="courier, monospaced"><A></FONT></CODE>. For this example we can |
| assume that these element types will be assigned the values 0, 1 and 2. |
| Now, lets say we are transforming this XML document:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| <?xml version="1.0"?> |
| |
| <A> |
| The crocodile cried: |
| <F>foo</F> |
| <B>bar</B> |
| <B>baz</B> |
| </A> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This XML document has the elements <CODE><FONT face="courier, monospaced"><A></FONT></CODE>, |
| <CODE><FONT face="courier, monospaced"><B></FONT></CODE> and <CODE><FONT face="courier, monospaced"><F></FONT></CODE>, which we assume are |
| assigned the types 7, 8 and 9 respectively (the numbers below that are |
| assigned for specific element types, such as the root node, text nodes,etc). |
| This causes a mismatch between the type used for <CODE><FONT face="courier, monospaced"><B></FONT></CODE> in |
| the translet and the type used for <CODE><FONT face="courier, monospaced"><B></FONT></CODE> in the DOM. The |
| DOMAdapter class (which mediates between the DOM and the translet) has been |
| given two tables for convertint between the two types; <CODE><FONT face="courier, monospaced">mapping</FONT></CODE> |
| for mapping from internal to external types, and <CODE><FONT face="courier, monospaced">reverseMapping</FONT></CODE> |
| for the other way around.</P> |
| |
| <P>The translet contains a <CODE><FONT face="courier, monospaced">String[]</FONT></CODE> array called |
| <CODE><FONT face="courier, monospaced">namesArray</FONT></CODE>. This array contains all the element and attribute |
| names that were referenced in the stylesheet. In our example, this array |
| would contain these string (in this specific order): "B", |
| "C" and "A". This array is passed as one of the |
| parameters to the DOM adapter constructor (the other parameter is the DOM |
| itself). The DOM adapter passes this table on to the DOM. The DOM generates |
| a hashtable that maps its known element names to the types the translet |
| knows. The DOM does this by going through the <CODE><FONT face="courier, monospaced">namesArray</FONT></CODE> from |
| the translet sequentially, looks up each name in the hashtable, and is then |
| able to map the internal type to an external type. The result is then passed |
| back to the DOM adapter.</P> |
| |
| <P>External types that are not interesting for the translet (such as the |
| type for <CODE><FONT face="courier, monospaced"><F></FONT></CODE> elements in the example above) are mapped |
| to a generic <CODE><FONT face="courier, monospaced">"ELEMENT"</FONT></CODE> type (integer value 3), and are more or |
| less ignored by the translet. Uninterresting attributes are similarly |
| mapped to internal type <CODE><FONT face="courier, monospaced">"ATTRIBUTE"</FONT></CODE> (integer value 4).</P> |
| |
| <P>It is important that we separate the DOM from the translet. In several |
| cases we want the DOM as a structure completely independent from the |
| translet - even though the DOM is a structure internal to XSLTC. One such |
| case is when transformations are offered by a servlet as a web service. |
| Any DOM that is built should potentially be stored in a cache and made |
| available for simultaneous access by several translet/servlet couples.</P> |
| |
| <P><IMG align="right" alt="runtime_type_mapping.gif" border="0" hspace="4" src="images/runtime_type_mapping.gif" vspace="4"><BR clear="all"></P> |
| <P><I>Figure 2: Two translets accessing a single dom using different type mappings</I></P> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| |
| |
| <A name="mainloop"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Main program loop</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>The main body of the translet is the <CODE><FONT face="courier, monospaced">applyTemplates()</FONT></CODE> |
| method. This method goes through these steps:</P> |
| |
| <UL> |
| <LI> |
| Get the next node from the node iterator |
| </LI> |
| <LI> |
| Get the internal type of this node. The DOMAdapter object holds the |
| internal/external type mapping table, and it will supply the translet |
| with the internal type of the current node. |
| </LI> |
| <LI> |
| Execute a switch statement on the internal node type. There will be |
| one "case" label for each recognised node type - this includes the |
| first 7 internal node types. |
| </LI> |
| </UL> |
| |
| <P>The root node will have internal type 0 and will cause any initial |
| literal elements to be output. Text nodes will have internal node type 1 |
| and will simply be dumped to the output handler. Unrecognized elements |
| will have internal node type 3 and will be given the default treatment |
| (a new iterator is created for the node's children, and this iterator |
| is passed with a recursive call to <CODE><FONT face="courier, monospaced">applyTemplates()</FONT></CODE>). |
| Unrecognised attribute nodes (type 4) will be handled like text nodes. |
| This makes up the default (built in) templates of any stylesheet. Then, |
| we add one <CODE><FONT face="courier, monospaced">"case"</FONT></CODE>for each node type that is matched by any |
| pattern in the stylesheet. The <CODE><FONT face="courier, monospaced">switch()</FONT></CODE> statement in |
| <CODE><FONT face="courier, monospaced">applyTemplates</FONT></CODE> will thereby look something like this:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| public void applyTemplates(DOM dom, NodeIterator, |
| TransletOutputHandler handler) { |
| |
| // get nodes from iterator |
| while ((node = iterator.next()) != END) { |
| // get internal node type |
| switch(DOM.getType(node)) { |
| |
| case 0: // root |
| outputPreable(handler); |
| break; |
| case 1: // text |
| DOM.characters(node,handler); |
| break; |
| case 3: // unrecognised element |
| NodeIterator newIterator = DOM.getChildren(node); |
| applyTemplates(DOM,newIterator,handler); |
| break; |
| case 4: // unrecognised attribute |
| DOM.characters(node,handler); |
| break; |
| case 7: // elements of type <B> |
| someCompiledCode(); |
| break; |
| case 8: // elements of type <C> |
| otherCompiledCode(); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>Each recognised element will have its own piece of compiled code.</P> |
| |
| <P>Note that each "case" will not lead directly to a single template. |
| There may be several templates that match node type 7 |
| (say <CODE><FONT face="courier, monospaced"><B></FONT></CODE>). In the sample stylesheet in the previous |
| chapter we have to templates that would match a node <CODE><FONT face="courier, monospaced"><B></FONT></CODE>. |
| We have one <CODE><FONT face="courier, monospaced">match="//B"</FONT></CODE> (match just any <CODE><FONT face="courier, monospaced"><B></FONT></CODE> |
| element) and one <CODE><FONT face="courier, monospaced">match="A/B"</FONT></CODE> (match a <CODE><FONT face="courier, monospaced"><B></FONT></CODE> |
| element that is a child of a <CODE><FONT face="courier, monospaced"><A></FONT></CODE> element). In this case |
| we would have to compile code that first gets the type of the current node's |
| parent, and then compared this type with the type for |
| <CODE><FONT face="courier, monospaced"><A></FONT></CODE>. If there was no match we will have executed the |
| first <CODE><FONT face="courier, monospaced"><xsl:for-each></FONT></CODE> element, but if there was a match |
| we will have executed the last one. Consequentally, the compiler will |
| generate the following code (well, it will look like this anyway):</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| switch(DOM.getType(node)) { |
| : |
| : |
| case 7: // elements of type <B> |
| int parent = DOM.getParent(node); |
| if (DOM.getType(parent) == 9) // type 9 = elements <A> |
| someCompiledCode(); |
| else |
| evenOtherCompiledCode(); |
| break; |
| : |
| : |
| } |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>We could do the same for namespaces, that is, assign a numeric value |
| to every namespace that is references in the stylesheet, and use an |
| <CODE><FONT face="courier, monospaced">"if"</FONT></CODE> statement for each namespace that needs to be checked for |
| each type. Lets say we had a stylesheet like this:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| <?xml version="1.0"?> |
| <xsl:stylesheet version="1.0" xmlns:xsl="blahblahblah"> |
| |
| <xsl:template match="/" |
| xmlns:foo="http://foo.com/spec" |
| xmlns:bar="http://bar.net/ref"> |
| <xsl:for-each select="foo:A"> |
| <xsl:apply-templates select="." /> |
| </xsl:for-each> |
| <xsl:for-each select="bar:A"> |
| <xsl:apply-templates select="." /> |
| </xsl:for-each> |
| </xsl:template> |
| |
| </xsl:stylesheet> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>And a stylesheet like this:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| <?xml version="1.0"?> |
| |
| <DOC xmlns:foo="http://foo.com/spec" |
| xmlns:bar="http://bar.net/ref"> |
| <foo:A>In foo namespace</foo:A> |
| <bar:A>In bar namespace</bar:A> |
| </DOC> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>We could still keep the same type for all <CODE><FONT face="courier, monospaced"><A></FONT></CODE> elements |
| regardless of what namespace they are in, and use the same <CODE><FONT face="courier, monospaced">"if"</FONT></CODE> |
| structure within the <CODE><FONT face="courier, monospaced">switch()</FONT></CODE> statement above. The other option |
| is to assign different types to <CODE><FONT face="courier, monospaced"><foo:A></FONT></CODE> and |
| <CODE><FONT face="courier, monospaced"><bar:A></FONT></CODE> elements. The latter is the option we chose, and |
| it is described in detail in the namespace design document.</P> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| |
| |
| <A name="library"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Runtime library</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>The runtime library offers basic functionality to the translet at |
| runtime. It is analoguous to UNIX's <CODE><FONT face="courier, monospaced">libc</FONT></CODE>. The whole runtime |
| library is contained in a single class file:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| org.apache.xalan.xsltc.runtime.BasisLibrary |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This class contains a large set of static methods that are invoked by |
| the translet. These methods are largely independent from eachother, and |
| they implement the following:</P> |
| |
| <UL> |
| <LI>simple XPath functions that do not require a lot of code |
| compiled into the translet class</LI> |
| <LI>functions for formatting decimal numbers to strings</LI> |
| <LI>functions for comparing nodes, node-sets and strings - used by |
| equality expressions, predicates and other</LI> |
| <LI>functions for generating localised error messages</LI> |
| </UL> |
| |
| <P>The runtime library is a central part of XSLTC. But, as metioned earlier, |
| the functions within the library are rarely related, so there is no real |
| overall design/architecture. The only common attribute of many of the |
| methods in the library is that all static methods that implement an XPath |
| function and with a capital <CODE><FONT face="courier, monospaced">F</FONT></CODE>.</P> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| |
| |
| <A name="output"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Output handler</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| |
| <P>The translet passes its output to an output post-processor before the |
| final result is handed to the client application over a standard SAX |
| interface. The interface between the translet and the output handler is |
| very similar to a SAX interface, but it has a few non-standard additions. |
| This interface is described in this file:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| org.apache.xalan.xsltc.TransletOutputHandler |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This interface is implemented by:</P> |
| |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| org.apache.xalan.xsltc.runtime.TextOutput |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| |
| <P>This class, despite its name, handles all types of output (XML, HTML and |
| TEXT). Our initial idea was to have a base class implementing the |
| <CODE><FONT face="courier, monospaced">TransletOutputHandler</FONT></CODE> interface, and then have one subclass |
| for each of the output types. This proved very difficult, as the output |
| type is not always known until after the transformation has started and |
| some elements have been output. But, this is an area where a change like |
| that has the potential to increase performance significantly. Output |
| handling has a lot to do with analyzing string contents, and by narrowing |
| down the number of string comparisons and string updates one can acomplish |
| a lot.</P> |
| |
| <P>The main tasks of the output handler are:</P> |
| |
| <UL> |
| <LI>determine the output type based on the output generated by the |
| translet (not always necessary)</LI> |
| <LI>generate SAX events for the client application</LI> |
| <LI>insert the necessary namespace declarations in the output</LI> |
| <LI>escape special characters in the output</LI> |
| <LI>insert <DOCTYPE> and <META> elements in HTML output</LI> |
| </UL> |
| |
| <P>There is a very clear link between the output handler and the |
| <CODE><FONT face="courier, monospaced">org.apache.xalan.xsltc.compiler.Output</FONT></CODE> class that handles |
| the <CODE><FONT face="courier, monospaced"><xsl:output></FONT></CODE> element. The <CODE><FONT face="courier, monospaced">Output</FONT></CODE> class |
| stores many output settings and parameters in the translet class file and |
| the translet passes these on to the output handler.</P> |
| |
| </FONT></TD></TR></TABLE><BR> |
| |
| </TD></TR></TABLE></TD></TR></TABLE><BR><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD bgcolor="#0086b2"><IMG alt="dot" height="1" src="resources/dot.gif" width="1"></TD></TR><TR><TD align="center"><FONT color="#0086b2" size="-1"><I> |
| Copyright © 2004 The Apache Software Foundation. |
| All Rights Reserved. |
| </I></FONT></TD></TR></TABLE></BODY></HTML> |