| <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| <html> |
| <head> |
| <title>ASF: XSLTC Internal DOM</title> |
| <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> |
| <meta http-equiv="Content-Style-Type" content="text/css" /> |
| <link rel="stylesheet" type="text/css" href="resources/apache-xalan.css" /> |
| </head> |
| <!-- |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| --> |
| <body> |
| <div id="title"> |
| <table class="HdrTitle"> |
| <tbody> |
| <tr> |
| <th rowspan="2"> |
| <a href="../index.html"> |
| <img alt="Trademark Logo" src="resources/XalanJ-Logo-tm.png" width="190" height="90" /> |
| </a> |
| </th> |
| <th text-align="center" width="75%"> |
| <a href="index.html">XSLTC Design</a> |
| </th> |
| </tr> |
| <tr> |
| <td valign="middle">XSLTC Internal DOM</td> |
| </tr> |
| </tbody> |
| </table> |
| <table class="HdrButtons" align="center" border="1"> |
| <tbody> |
| <tr> |
| <td> |
| <a href="http://www.apache.org">Apache Foundation</a> |
| </td> |
| <td> |
| <a href="http://xalan.apache.org">Xalan Project</a> |
| </td> |
| <td> |
| <a href="http://xerces.apache.org">Xerces Project</a> |
| </td> |
| <td> |
| <a href="http://www.w3.org/TR">Web Consortium</a> |
| </td> |
| <td> |
| <a href="http://www.oasis-open.org/standards">Oasis Open</a> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| <div id="navLeft"> |
| <ul> |
| <li> |
| <a href="index.html">Overview</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsltc_compiler.html">Compiler design</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsl_whitespace_design.html">Whitespace</a> |
| </li> |
| <li> |
| <a href="xsl_sort_design.html">xsl:sort</a> |
| </li> |
| <li> |
| <a href="xsl_key_design.html">Keys</a> |
| </li> |
| <li> |
| <a href="xsl_comment_design.html">Comment design</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsl_lang_design.html">lang()</a> |
| </li> |
| <li> |
| <a href="xsl_unparsed_design.html">Unparsed entities</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsl_if_design.html">If design</a> |
| </li> |
| <li> |
| <a href="xsl_choose_design.html">Choose|When|Otherwise design</a> |
| </li> |
| <li> |
| <a href="xsl_include_design.html">Include|Import design</a> |
| </li> |
| <li> |
| <a href="xsl_variable_design.html">Variable|Param design</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsltc_runtime.html">Runtime</a> |
| </li></ul><hr /><ul> |
| <li>Internal DOM<br /> |
| </li> |
| <li> |
| <a href="xsltc_namespace.html">Namespaces</a> |
| </li></ul><hr /><ul> |
| <li> |
| <a href="xsltc_trax.html">Translet & TrAX</a> |
| </li> |
| <li> |
| <a href="xsltc_predicates.html">XPath Predicates</a> |
| </li> |
| <li> |
| <a href="xsltc_iterators.html">Xsltc Iterators</a> |
| </li> |
| <li> |
| <a href="xsltc_native_api.html">Xsltc Native API</a> |
| </li> |
| <li> |
| <a href="xsltc_trax_api.html">Xsltc TrAX API</a> |
| </li> |
| <li> |
| <a href="xsltc_performance.html">Performance Hints</a> |
| </li> |
| </ul> |
| </div> |
| <div id="content"> |
| <h2>XSLTC Internal DOM</h2> |
| |
| <ul> |
| <li> |
| <a href="#functionality">General functionlaity</a> |
| </li> |
| <li> |
| <a href="#components">Components of the internal DOM</a> |
| </li> |
| <li> |
| <a href="#structure">Internal structure</a> |
| </li> |
| <li> |
| <a href="#navigation">Tree navigation</a> |
| </li> |
| <li> |
| <a href="#namespaces">Namespaces</a> |
| </li> |
| <li> |
| <a href="#w3c">W3C DOM2 navigation support</a> |
| </li> |
| <li> |
| <a href="#adapter">The DOM adapter - DOMAdapter</a> |
| </li> |
| <li> |
| <a href="#multiplexer">The DOM multiplexer - MultiDOM</a> |
| </li> |
| <li> |
| <a href="#builder">The DOM builder - DOMImpl$DOMBuilder</a> |
| </li> |
| </ul> |
| |
| <a name="functionality"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>General functionality</h3> |
| <p>The internal DOM gives the translet access to the XML document(s) it has |
| to transform. The interface to the internal DOM is specified in the DOM.java |
| class. This is the interface that the translet uses to access the DOM. |
| There is also an interface specified for DOM caches -- DOMCache.java</p> |
| |
| <a name="components"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>Components of the internal DOM</h3> |
| |
| <p>This DOM interface is implemented by three classes:</p> |
| <ul> |
| <li> |
| <b>org.apache.xalan.xsltc.dom.DOMImpl</b> |
| <br /> |
| <br /> |
| This is the main DOM class. An instance of this class contains the nodes |
| of a <b>single</b> XML document.<br /> |
| <br /> |
| </li> |
| <li> |
| <b>org.apache.xalan.xsltc.dom.MultiDOM</b> |
| <br /> |
| <br /> |
| This class is best described as a DOM multiplexer. XSLTC was initially |
| designed to operate on a single XML document, and the initial DOM and |
| the DOM interface were designed and implemented without the |
| <code>document()</code> function in mind. This class will allow a translet |
| to access multiple DOMs through the original DOM interface.<br /> |
| <br /> |
| </li> |
| <li> |
| <b>org.apache.xalan.xsltc.dom.DOMAdapter</b> |
| <br /> |
| <br /> |
| The DOM adapter is a mediator between a DOMImpl or a MultiDOM object and |
| a single translet. A DOMAdapter object contains mappings and reverse |
| mappings between node types in the DOM(s) and node types in the translet. |
| This mediator is needed to allow several translets access to a single DOM. |
| <br /> |
| <br /> |
| </li> |
| <li> |
| <b>org.apache.xalan.xsltc.dom.DocumentCache</b> |
| <br /> |
| <br /> |
| A sample DOM cache (implementing DOMCache) that is used with our sample |
| transformation applications. |
| </li> |
| </ul> |
| |
| <p> |
| <img src="DOMInterface.gif" alt="DOMInterface.gif" /> |
| </p> |
| <p> |
| <b> |
| <i>Figure 1: Main components of the internal DOM</i> |
| </b> |
| </p> |
| |
| <p>The figure above shows how several translets can access one or more |
| internal DOM from a shared pool of cached DOMs. A translet can also access a |
| DOM tree outside of a cache. The Stylesheet class that represents the XSL |
| stylesheet to compile contains a flag that indicates if the translet uses the |
| <code>document()</code> function. The code compiled into the translet will act |
| accordingly and instanciate a MultiDOM object if needed (this code is compiled |
| in the compiler's <code>Stylesheet.compileTransform()</code> method).</p> |
| |
| <a name="structure"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>Internal Structure</h3> |
| <ul> |
| <li> |
| <a href="#node-id">Node identification</a> |
| </li> |
| <li> |
| <a href="#element-nodes">Element nodes</a> |
| </li> |
| <li> |
| <a href="#attribute-nodes">Attribute nodes</a> |
| </li> |
| <li> |
| <a href="#text-nodes">Text nodes</a> |
| </li> |
| <li> |
| <a href="#comment-nodes">Comment nodes</a> |
| </li> |
| <li> |
| <a href="#pi" />Processing instructions</li> |
| </ul> |
| <a name="node-id"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Node identifation</h4> |
| |
| <p>Each node in the DOM is represented by an integer. This integer is an |
| index into a series of arrays that describes the node. Most important is |
| the <code>_type[]</code> array, which holds the (DOM internal) node type. There |
| are some general node types that are described in the DOM.java interface:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| public final static int ROOT = 0; |
| public final static int TEXT = 1; |
| public final static int UNUSED = 2; |
| public final static int ELEMENT = 3; |
| public final static int ATTRIBUTE = 4; |
| public final static int PROCESSING_INSTRUCTION = 5; |
| public final static int COMMENT = 6; |
| public final static int NTYPES = 7; |
| </pre> |
| </blockquote> |
| |
| <p>Element and attribute nodes will be assigned types based on their expanded |
| QNames. The <code>_type[]</code> array is used for this:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int type = _type[node]; // get node type |
| </pre> |
| </blockquote> |
| |
| <p>The node type can be used to look up the element/attribute name in the |
| element/attribute name array <code>_namesArray[]</code>:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| String name = _namesArray[type-NTYPES]; // get node element name |
| </pre> |
| </blockquote> |
| |
| <p>The resulting string contains the full, expanded QName of the element or |
| attribute. Retrieving the namespace URI of an element/attribute is done in a |
| very similar fashion:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int nstype = _namespace[type-NTYPES]; // get namespace type |
| String namespace = _nsNamesArray[nstype]; // get node namespace name |
| </pre> |
| </blockquote> |
| <a name="element-nodes"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Element nodes</h4> |
| |
| <p>The contents of an element node (child nodes) can be identified using |
| the <code>_offsetOrChild[]</code> and <code>_nextSibling[]</code> arrays. The |
| <code>_offsetOrChild[]</code> array will give you the first child of an element |
| node:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int child = _offsetOrChild[node]; // first child |
| child = _nextSibling[child]; // next child |
| </pre> |
| </blockquote> |
| |
| <p>The last child will have a "<code>_nextSibling[]</code>" of 0 (zero). |
| This value is OK since the root node (the 0 node) will not be a child of |
| any element.</p> |
| |
| <a name="attribute-nodes"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Attribute nodes</h4> |
| |
| <p>The first attribute node of an element is found by a lookup in the |
| <code>_lengthOrAttr[]</code> array using the node index:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int attribute = _offsetOrChild[node]; // first attribute |
| attribute = _nextSibling[attribute]; // next attribute |
| </pre> |
| </blockquote> |
| |
| <p>The names of attributes are contained in the <code>_namesArray[]</code> just |
| like the names of element nodes. The value of attributes are store the same |
| way as text nodes:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int offset = _offsetOrChild[attribute]; // offset into character array |
| int length = _lengthOrAttr[attribute]; // length of attribute value |
| String value = new String(_text, offset, length); |
| </pre> |
| </blockquote> |
| <a name="text-nodes"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Text nodes</h4> |
| |
| <p>Text nodes are stored identically to attribute values. See the previous |
| section on <a href="#attribute-nodes">attribute nodes</a>.</p> |
| <a name="comment-nodes"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Comment nodes</h4> |
| |
| <p>The internal DOM does currently <b>not</b> contain comment nodes. Yes, I |
| am quite aware that the DOM has a type assigned to comment nodes, but comments |
| are still not inserted into the DOM.</p> |
| <a name="pi"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Processing instructions</h4> |
| |
| <p>Processing instructions are handled as text nodes. These nodes are stored |
| identically to attribute values. See the previous section on |
| <a href="#attribute-nodes">attribute nodes</a>.</p> |
| |
| <a name="navigation"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>Tree navigation</h3> |
| |
| <p>The DOM implementation contains a series of iterator that implement the |
| XPath axis. All these iterators implement the NodeIterator interface and |
| extend the NodeIteratorBase base class. These iterators do the job of |
| navigating the tree using the <code>_offsetOrChild[]</code>, <code>_nextSibling</code> |
| and <code>_parent[]</code> arrays. All iterators that handles XPath axis are |
| implemented as a private inner class of DOMImpl. The translet uses a handful |
| of methods to instanciate these iterators:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| public NodeIterator getIterator(); |
| public NodeIterator getChildren(final int node); |
| public NodeIterator getTypedChildren(final int type); |
| public NodeIterator getAxisIterator(final int axis); |
| public NodeIterator getTypedAxisIterator(final int axis, final int type); |
| public NodeIterator getNthDescendant(int node, int n); |
| public NodeIterator getNamespaceAxisIterator(final int axis, final int ns); |
| public NodeIterator orderNodes(NodeIterator source, int node); |
| </pre> |
| </blockquote> |
| |
| <p>There are a few iterators in addition to these, such as sorting/ordering |
| iterators and filtering iterators. These iterators are implemented in |
| separate classes and can be instanciated directly by the translet.</p> |
| |
| <a name="namespaces"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>Namespaces</h3> |
| |
| <p>Namespace support was added to the internal DOM at a late stage, and the |
| design and implementation of the DOM bears a few scars because of this. |
| There is a separate <a href="xsltc_namespace.html">design |
| document</a> that covers namespaces.</p> |
| |
| <a name="w3c"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>W3C DOM2 navigation support</h3> |
| |
| <p>The DOM has a few methods that give basic W3C-type DOM navigation. These |
| methods are:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| public Node makeNode(int index); |
| public Node makeNode(NodeIterator iter); |
| public NodeList makeNodeList(int index); |
| public NodeList makeNodeList(NodeIterator iter); |
| </pre> |
| </blockquote> |
| |
| <p>These methods return instances of inner classes of the DOM that implement |
| the W3C Node and NodeList interfaces.</p> |
| |
| <a name="adapter"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>The DOM adapter - DOMAdapter</h3> |
| <ul> |
| <li> |
| <a href="#translet-dom">Translet/DOM type mapping</a> |
| </li> |
| <li> |
| <a href="#whitespace">Whitespace text-node stripping</a> |
| </li> |
| <li> |
| <a href="#method-mapping">Method mapping</a> |
| </li> |
| </ul> |
| <a name="translet-dom"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Translet/DOM type mapping</h4> |
| |
| <p>The DOMAdapter class performs the mappings between DOM and translet node |
| types, and vice versa. These mappings are necessary in order for the translet |
| to correctly identify an element/attribute in the DOM and for the DOM to |
| correctly identify the element/attribute type of a typed iterator requested |
| by the translet. Note that the DOMAdapter also maps translet namespace types |
| to DOM namespace types, and vice versa.</p> |
| |
| <p>The DOMAdapter class has four global tables that hold the translet/DOM |
| type and namespace-type mappings. If the DOM knows an element as type |
| 19, the DOMAdapter will translate this to some other integer using the |
| <code>_mapping[]</code> array:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int domType = _mapping[transletType]; |
| </pre> |
| </blockquote> |
| |
| <p>This action will be performed when the DOM asks what type a specific node |
| is. The reverse is done then the translet wants an iterator for a specific |
| node type. The DOMAdapter must translate the translet-type to the type used |
| internally in the DOM by looking up the <code>_reverse[]</code> array:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| int transletType = _mapping[domType]; |
| </pre> |
| </blockquote> |
| |
| <p>There are two additional mapping tables: <code>_NSmapping[]</code> and |
| <code>_NSreverse[]</code> that do the same for namespace types.</p> |
| <a name="whitespace"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Whitespace text-node stripping</h4> |
| |
| <p>The DOMAdapter class has the additional function of stripping whitespace |
| nodes in the DOM. This functionality had to be put in the DOMAdapter, as |
| different translets will have different preferences for node stripping.</p> |
| <a name="method-mapping"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>Method mapping</h4> |
| |
| <p>The DOMAdapter class implements the same <code>DOM</code> interface as the |
| DOMImpl class. A DOMAdapter object will look like a DOMImpl tree, but the |
| translet can access it directly without being concerned with type mapping |
| and whitespace stripping. The <code>getTypedChildren()</code> demonstrates very |
| well how this is done:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| public NodeIterator getTypedChildren(int type) { |
| // Get the DOM type for the requested typed iterator |
| final int domType = _reverse[type]; |
| // Now get the typed child iterator from the DOMImpl object |
| NodeIterator iterator = _domImpl.getTypedChildren(domType); |
| // Wrap the iterator in a WS stripping iterator if child-nodes are text nodes |
| if ((domType == DOM.TEXT) && (_filter != null)) |
| iterator = _domImpl.strippingIterator(iterator,_mapping,_filter); |
| return(iterator); |
| } |
| </pre> |
| </blockquote> |
| |
| <a name="multiplexer"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>The DOM multiplexer - MultiDOM</h3> |
| |
| <p>The DOM multiplexer class is only used when the compiled stylesheet uses |
| the <code>document()</code> function. An instance of the MultiDOM class also |
| implements the DOM interface, so that it can be accessed in the same way |
| as a DOMAdapter object.</p> |
| |
| <p>A node in the DOM is identified by an integer. The first 8 bits of this |
| integer are used to identify the DOM in which the node belongs, while the |
| lower 24 bits are used to identify the node within the DOM:</p> |
| <table border="1"> |
| <tr> |
| <td class="content" rowspan="1" colspan="1">31-24</td> |
| <td class="content" rowspan="1" colspan="1">23-16</td> |
| <td class="content" rowspan="1" colspan="1">16-8</td> |
| <td class="content" rowspan="1" colspan="1">7-0</td> |
| </tr> |
| <tr> |
| <td class="content" rowspan="1" colspan="1">DOM id</td> |
| <td class="content" rowspan="1" colspan="3">node id</td> |
| </tr> |
| </table> |
| |
| <p>The DOM multiplexer has an array of DOMAdapter objects. The topmost 8 |
| bits of the identifier is used to find the correct DOM from the array. Then |
| the lower 24 bits are used in calls to methods in the DOMAdapter object:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| public int getParent(int node) { |
| return _adapters[node>>>24].getParent(node & 0x00ffffff) | node & 0xff000000; |
| } |
| </pre> |
| </blockquote> |
| |
| <p>Note that the node identifier returned by this method has the same upper 8 |
| bits as the input node. This is why we <code>OR</code> the result from |
| <code>DOMAdapter.getParent()</code> with the top 8 bits of the input node.</p> |
| |
| <a name="builder"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h3>The DOM builder - DOMImpl$DOMBuilder</h3> |
| <ul> |
| <li> |
| <a href="#startelement">startElement()</a> |
| </li> |
| <li> |
| <a href="#endelement">endElement()</a> |
| </li> |
| <li> |
| <a href="#startprefixmapping">startPrefixMapping()</a> |
| </li> |
| <li> |
| <a href="#endprefixmapping">endPrefixMapping()</a> |
| </li> |
| <li> |
| <a href="#characters">characters()</a> |
| </li> |
| <li> |
| <a href="#startdocument">startDocument()</a> |
| </li> |
| <li> |
| <a href="#enddocument">endDocument()</a> |
| </li> |
| </ul> |
| |
| <p>The DOM builder is an inner class of the DOM implementation. The builder |
| implements the SAX2 <code>ContentHandler</code> interface and populates the DOM |
| by receiving SAX2 events from a SAX2 parser (presently xerces). An instance |
| of the DOM builder class can be retrieved from <code>DOMImpl.getBuilder()</code> |
| method, and this handler can be set as an XMLReader's content handler:</p> |
| |
| <blockquote class="source"> |
| <pre> |
| final SAXParserFactory factory = SAXParserFactory.newInstance(); |
| final SAXParser parser = factory.newSAXParser(); |
| final XMLReader reader = parser.getXMLReader(); |
| final DOMImpl dom = new DOMImpl(); |
| reader.setContentHandler(dom.getBuilder()); |
| </pre> |
| </blockquote> |
| |
| <p>The DOM builder will start to populate the DOM once the XML parser starts |
| generating SAX2 events:</p> |
| <a name="startelement"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>startElement()</h4> |
| |
| <p>This method can be called in one of two ways; either with the expanded |
| QName (the element's separate uri and local name are supplied) or as a |
| normal QName (one String on the format prefix:local-name). The DOM stores |
| elements as expanded QNames so it needs to know the element's namespace URI. |
| Since the URI is not supplied with this call, we have to keep track of |
| namespace prefix/uri mappings while we're building the DOM. See |
| <code> |
| <a href="#startprefixmapping">startPrefixMapping()</a> |
| </code> below for details on |
| namespace handling.</p> |
| |
| <p>The <code>startElement()</code> inserts the element as a child of the current |
| parent element, creates attribute nodes for all attributes in the supplied |
| "<code>Attributes</code>" attribute list (by a series of calls to |
| <code>makeAttributeNode()</code>), and finally creates the actual element node |
| (by calling <code>internElement()</code>, which inserts a new entry in the |
| <code>_type[]</code> array).</p> |
| <a name="endelement"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>endElement()</h4> |
| |
| <p>This method does some cleanup after the <code>startElement()</code> method, |
| such as revering <code>xml:space</code> settings and linking the element's |
| child nodes.</p> |
| <a name="startprefixmapping"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>startPrefixMapping()</h4> |
| |
| <p>This method is called for each namespace declaration in the source |
| document. The parser should call this method before the prefix is referenced |
| in a QName that is passed to the <code>startElement()</code> call. Namespace |
| prefix/uri mappings are stored in a Hashtable structure. Namespace prefixes |
| are used as the keys in the Hashtable, and each key maps to a Stack that |
| contains the various URIs that the prefix maps to. The URI on top of the |
| stack is the URI that the prefix currently maps to.</p> |
| |
| |
| <p> |
| <img src="namespace_stack.gif" alt="namespace_stack.gif" /> |
| </p> |
| <p> |
| <b> |
| <i>Figure 2: Namespace handling in the DOM builder</i> |
| </b> |
| </p> |
| |
| |
| <p>Each call to <code>startPrefixMapping()</code> results in a lookup in the |
| Hashtable (using the prefix), and a <code>push()</code> of the URI onto the |
| Stack that the prefix maps to.</p> |
| <a name="endprefixmapping"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>endPrefixMapping()</h4> |
| |
| <p>A namespace prefix/uri mapping is closed by locating the Stack for the |
| prefix, and then <code>pop()</code>'ing the topmost URI off this Stack.</p> |
| <a name="characters"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>characters()</h4> |
| |
| <p>Text nodes are stored as simple character sequences in the character array |
| <code>_text[]</code>. The start and lenght of a node's text can be determined by |
| using the node index to look up <code>_offsetOrChild[]</code> and |
| <code>_lengthOrAttribute[]</code>.</p> |
| |
| <p>We want to re-use character sequences if two or more text nodes have |
| identical content. This can be achieved by having two different text node |
| indexes map to the same character sequence. The <code>maybeReuseText()</code> |
| method is always called before a new character string is stored in the |
| <code>_text[]</code> array. This method will locate the offset of an existing |
| instance of a character sequence.</p> |
| <a name="startdocument"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>startDocument()</h4> |
| |
| <p>This method initialises a bunch of data structures that are used by the |
| builder. It also pushes the default namespace on the namespace stack (so that |
| the "" prefix maps to the <code>null</code> namespace).</p> |
| <a name="enddocument"></a> |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| <h4>endDocument()</h4> |
| |
| <p>This method builds the <code>_namesArray[]</code>, <code>_namespace[]</code> |
| and <code>_nsNamesArray[]</code> structures from temporary datastructures used |
| in the DOM builder.</p> |
| |
| |
| |
| <p align="right" size="2"> |
| <a href="#content">(top)</a> |
| </p> |
| </div> |
| <div id="footer">Copyright © 1999-2014 The Apache Software Foundation<br />Apache, Xalan, and the Feather logo are trademarks of The Apache Software Foundation<div class="small">Web Page created on - Thu 2014-05-15</div> |
| </div> |
| </body> |
| </html> |