/** * Get a DTM to be used as a container for a dynamic Result Tree Fragment. This will always be an * instance of (derived from? equivalent to?) SAX2DTM, since each RTF is constructed by * temporarily redirecting our SAX output to it. It may be a single DTM containing for multiple * fragments, if the implementation supports that. * * @return a non-null DTM reference. */ public DTM getRTFDTM() { SAX2RTFDTM rtfdtm; // We probably should _NOT_ be applying whitespace filtering at this stage! // // Some magic has been applied in DTMManagerDefault to recognize this set of options // and generate an instance of DTM which can contain multiple documents // (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but // I didn't want to change the manager API at this time, or expose // too many dependencies on its internals. (Ideally, I'd like to move // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly // specify the subclass here.) if (m_rtfdtm_stack == null) { m_rtfdtm_stack = new Vector(); rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null, true, null, false, false); m_rtfdtm_stack.addElement(rtfdtm); ++m_which_rtfdtm; } else if (m_which_rtfdtm < 0) { rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack.elementAt(++m_which_rtfdtm); } else { rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack.elementAt(m_which_rtfdtm); // It might already be under construction -- the classic example would be // an xsl:variable which uses xsl:call-template as part of its value. To // handle this recursion, we have to start a new RTF DTM, pushing the old // one onto a stack so we can return to it. This is not as uncommon a case // as we might wish, unfortunately, as some folks insist on coding XSLT // as if it were a procedural language... if (rtfdtm.isTreeIncomplete()) { if (++m_which_rtfdtm < m_rtfdtm_stack.size()) rtfdtm = (SAX2RTFDTM) m_rtfdtm_stack.elementAt(m_which_rtfdtm); else { rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null, true, null, false, false); m_rtfdtm_stack.addElement(rtfdtm); } } } return rtfdtm; }
/** * Get a DTM to be used as a container for a global Result Tree Fragment. This will always be an * instance of (derived from? equivalent to?) SAX2DTM, since each RTF is constructed by * temporarily redirecting our SAX output to it. It may be a single DTM containing for multiple * fragments, if the implementation supports that. * * <p>Note: The distinction between this method and getRTFDTM() is that the latter allocates space * from the dynamic variable stack (m_rtfdtm_stack), which may be pruned away again as the * templates which defined those variables are exited. Global variables may be bound late (see * XUnresolvedVariable), and never want to be discarded, hence we need to allocate them separately * and don't actually need a stack to track them. * * @return a non-null DTM reference. */ public DTM getGlobalRTFDTM() { // We probably should _NOT_ be applying whitespace filtering at this stage! // // Some magic has been applied in DTMManagerDefault to recognize this set of options // and generate an instance of DTM which can contain multiple documents // (SAX2RTFDTM). Perhaps not the optimal way of achieving that result, but // I didn't want to change the manager API at this time, or expose // too many dependencies on its internals. (Ideally, I'd like to move // isTreeIncomplete all the way up to DTM, so we wouldn't need to explicitly // specify the subclass here.) // If it doesn't exist, or if the one already existing is in the middle of // being constructed, we need to obtain a new DTM to write into. I'm not sure // the latter will ever arise, but I'd rather be just a bit paranoid.. if (m_global_rtfdtm == null || m_global_rtfdtm.isTreeIncomplete()) { m_global_rtfdtm = (SAX2RTFDTM) m_dtmManager.getDTM(null, true, null, false, false); } return m_global_rtfdtm; }