transformerimpl.java
来自「java jdk 1.4的源码」· Java 代码 · 共 2,145 行 · 第 1/5 页
JAVA
2,145 行
m_xcontext.getSourceTreeManager().setURIResolver(resolver); } } /** * Get an object that will be used to resolve URIs used in * document(), etc. * * @return An object that implements the URIResolver interface, * or null. */ public URIResolver getURIResolver() { return m_xcontext.getSourceTreeManager().getURIResolver(); } // ======== End Transformer Implementation ======== /** * Set the content event handler. * * @param resolver The new content handler. * * NEEDSDOC @param handler * @throws java.lang.NullPointerException If the handler * is null. * @see org.xml.sax.XMLReader#setContentHandler */ public void setContentHandler(ContentHandler handler) { if (handler == null) { throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_CONTENT_HANDLER, null)); //"Null content handler"); } else { m_outputContentHandler = handler; if (null == m_resultTreeHandler) m_resultTreeHandler = new ResultTreeHandler(this, handler); else m_resultTreeHandler.setContentHandler(handler); } } /** * Get the content event handler. * * @return The current content handler, or null if none was set. * @see org.xml.sax.XMLReader#getContentHandler */ public ContentHandler getContentHandler() { return m_outputContentHandler; } /** * <meta name="usage" content="advanced"/> * Given a stylesheet element, create a result tree fragment from it's * contents. The fragment will be built within the shared RTF DTM system * used as a variable stack. * @param templateParent The template element that holds the fragment. * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException */ public int transformToRTF(ElemTemplateElement templateParent) throws TransformerException { // Retrieve a DTM to contain the RTF. At this writing, this may be a // multi-document DTM (SAX2RTFDTM). DTM dtmFrag = m_xcontext.getRTFDTM(); return transformToRTF(templateParent,dtmFrag); } /** * <meta name="usage" content="advanced"/> * Given a stylesheet element, create a result tree fragment from it's * contents. The fragment will also use the shared DTM system, but will * obtain its space from the global variable pool rather than the dynamic * variable stack. This allows late binding of XUnresolvedVariables without * the risk that their content will be discarded when the variable stack * is popped. * * @param templateParent The template element that holds the fragment. * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException */ public int transformToGlobalRTF(ElemTemplateElement templateParent) throws TransformerException { // Retrieve a DTM to contain the RTF. At this writing, this may be a // multi-document DTM (SAX2RTFDTM). DTM dtmFrag = m_xcontext.getGlobalRTFDTM(); return transformToRTF(templateParent,dtmFrag); } /** * <meta name="usage" content="advanced"/> * Given a stylesheet element, create a result tree fragment from it's * contents. * @param templateParent The template element that holds the fragment. * @param dtmFrag The DTM to write the RTF into * @return the NodeHandle for the root node of the resulting RTF. * * @throws TransformerException */ private int transformToRTF(ElemTemplateElement templateParent,DTM dtmFrag) throws TransformerException { XPathContext xctxt = m_xcontext; ContentHandler rtfHandler = dtmFrag.getContentHandler(); // Obtain the ResultTreeFrag's root node. // NOTE: In SAX2RTFDTM, this value isn't available until after // the startDocument has been issued, so assignment has been moved // down a bit in the code. int resultFragment; // not yet reliably = dtmFrag.getDocument(); // Save the current result tree handler. ResultTreeHandler savedRTreeHandler = this.m_resultTreeHandler; // And make a new handler for the RTF. m_resultTreeHandler = new ResultTreeHandler(this, rtfHandler); ResultTreeHandler rth = m_resultTreeHandler; try { rth.startDocument(); // startDocument is "bottlenecked" in RTH. We need it acted upon immediately, // to set the DTM's state as in-progress, so that if the xsl:variable's body causes // further RTF activity we can keep that from bashing this DTM. rth.flushPending(); try { // Do the transformation of the child elements. executeChildTemplates(templateParent, true); // Make sure everything is flushed! rth.flushPending(); // Get the document ID. May not exist until the RTH has not only // received, but flushed, the startDocument, and may be invalid // again after the document has been closed (still debating that) // ... so waiting until just before the end seems simplest/safest. resultFragment = dtmFrag.getDocument(); } finally { rth.endDocument(); } } catch (org.xml.sax.SAXException se) { throw new TransformerException(se); } finally { // Restore the previous result tree handler. this.m_resultTreeHandler = savedRTreeHandler; } return resultFragment; } /** * <meta name="usage" content="internal"/> * Get the StringWriter pool, so that StringWriter * objects may be reused. * * @return The string writer pool, not null. */ public ObjectPool getStringWriterPool() { return m_stringWriterObjectPool; } /** * <meta name="usage" content="advanced"/> * Take the contents of a template element, process it, and * convert it to a string. * * @param elem The parent element whose children will be output * as a string. * @param transformer The XSLT transformer instance. * @param sourceNode The current source node context. * @param mode The current xslt mode. * * @return The stringized result of executing the elements children. * * @throws TransformerException */ public String transformToString(ElemTemplateElement elem) throws TransformerException { ElemTemplateElement firstChild = elem.getFirstChildElem(); if(null == firstChild) return ""; if(elem.hasTextLitOnly() && org.apache.xalan.processor.TransformerFactoryImpl.m_optimize) { return ((ElemTextLiteral)firstChild).getNodeValue(); } // Save the current result tree handler. ResultTreeHandler savedRTreeHandler = this.m_resultTreeHandler; // Create a Serializer object that will handle the SAX events // and build the ResultTreeFrag nodes. StringWriter sw = (StringWriter) m_stringWriterObjectPool.getInstance(); m_resultTreeHandler = (ResultTreeHandler) m_textResultHandlerObjectPool.getInstance(); Serializer serializer = m_resultTreeHandler.getSerializer(); try { if (null == serializer) { serializer = SerializerFactory.getSerializer(m_textformat.getProperties()); m_resultTreeHandler.setSerializer(serializer); serializer.setWriter(sw); ContentHandler shandler = serializer.asContentHandler(); m_resultTreeHandler.init(this, shandler); } else { // Leave Commented. -sb // serializer.setWriter(sw); // serializer.setOutputFormat(m_textformat); // ContentHandler shandler = serializer.asContentHandler(); // m_resultTreeHandler.setContentHandler(shandler); } } catch (IOException ioe) { throw new TransformerException(ioe); } String result; try { this.m_resultTreeHandler.startDocument(); // Do the transformation of the child elements. executeChildTemplates(elem, true); this.m_resultTreeHandler.endDocument(); result = sw.toString(); } catch (org.xml.sax.SAXException se) { throw new TransformerException(se); } finally { sw.getBuffer().setLength(0); try { sw.close(); } catch (Exception ioe){} m_stringWriterObjectPool.freeInstance(sw); m_textResultHandlerObjectPool.freeInstance(m_resultTreeHandler); m_resultTreeHandler.reset(); // Restore the previous result tree handler. m_resultTreeHandler = savedRTreeHandler; } return result; } /** * <meta name="usage" content="advanced"/> * Given an element and mode, find the corresponding * template and process the contents. * * @param xslInstruction The calling element. * @param template The template to use if xsl:for-each, or null. * @param child The source context node. * @param mode The current mode, may be null. * @throws TransformerException * @return true if applied a template, false if not. */ public boolean applyTemplateToNode(ElemTemplateElement xslInstruction, // xsl:apply-templates or xsl:for-each ElemTemplate template, int child) throws TransformerException { DTM dtm = m_xcontext.getDTM(child); short nodeType = dtm.getNodeType(child); boolean isDefaultTextRule = false; boolean isApplyImports = false; if (null == template) { int maxImportLevel, endImportLevel=0; isApplyImports = ((xslInstruction == null) ? false : xslInstruction.getXSLToken() == Constants.ELEMNAME_APPLY_IMPORTS); if (isApplyImports) { maxImportLevel = xslInstruction.getStylesheetComposed().getImportCountComposed() - 1; endImportLevel = xslInstruction.getStylesheetComposed().getEndImportCountComposed(); } else { maxImportLevel = -1; } // If we're trying an xsl:apply-imports at the top level (ie there are no // imported stylesheets), we need to indicate that there is no matching template. // The above logic will calculate a maxImportLevel of -1 which indicates // that we should find any template. This is because a value of -1 for // maxImportLevel has a special meaning. But we don't want that. // We want to match -no- templates. See bugzilla bug 1170. if (isApplyImports && (maxImportLevel == -1)) { template = null; } else { // Find the XSL template that is the best match for the // element. XPathContext xctxt = m_xcontext; try { xctxt.pushNamespaceContext(xslInstruction); QName mode = this.getMode(); if (isApplyImports) template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode, maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm); else template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode, m_quietConflictWarnings, dtm); } finally { xctxt.popNamespaceContext(); } } // If that didn't locate a node, fall back to a default template rule. // See http://www.w3.org/TR/xslt#built-in-rule. if (null == template) { switch (nodeType) { case DTM.DOCUMENT_FRAGMENT_NODE : case DTM.ELEMENT_NODE : template = m_stylesheetRoot.getDefaultRule(); break; case DTM.CDATA_SECTION_NODE : case DTM.TEXT_NODE : case DTM.ATTRIBUTE_NODE : template = m_stylesheetRoot.getDefaultTextRule(); isDefaultTextRule = true; break; case DTM.DOCUMENT_NODE : template = m_stylesheetRoot.getDefaultRootRule(); break; default : // No default rules for processing instructions and the like. return false; } } } // If we are processing the default text rule, then just clone // the value directly to the result tree. try { pushElemTemplateElement(template); m_xcontext.pushCurrentNode(child); pushPairCurrentMatched(template, child); // Fix copy copy29 test. if (!isApplyImports) { DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager()); m_xcontext.pushContextNodeList(cnl); } if (isDefaultTextRule) { switch (nodeType) { case DTM.CDATA_SECTION_NODE : case DTM.TEXT_NODE : ClonerToResultTree.cloneToResultTree(child, nodeType, dtm, getResultTreeHandler(), false); break; case DTM.ATTRIBUTE_NODE : dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false); break; } } else { // Fire a trace event for the template.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?