📄 xpathcontext.java
字号:
/** * Get the current namespace context for the xpath. * * @return the current prefix resolver for resolving prefixes to * namespace URLs. */ public final PrefixResolver getNamespaceContext() { return (PrefixResolver) m_prefixResolvers.peek(); } /** * Get the current namespace context for the xpath. * * @param pr the prefix resolver to be used for resolving prefixes to * namespace URLs. */ public final void setNamespaceContext(PrefixResolver pr) { m_prefixResolvers.setTop(pr); } /** * Push a current namespace context for the xpath. * * @param pr the prefix resolver to be used for resolving prefixes to * namespace URLs. */ public final void pushNamespaceContext(PrefixResolver pr) { m_prefixResolvers.push(pr); } /** * Just increment the namespace contest stack, so that setNamespaceContext * can be used on the slot. */ public final void pushNamespaceContextNull() { m_prefixResolvers.push(null); } /** * Pop the current namespace context for the xpath. */ public final void popNamespaceContext() { m_prefixResolvers.pop(); } //========================================================== // SECTION: Current TreeWalker contexts (for internal use) //========================================================== /** * Stack of AxesIterators. */ private Stack m_axesIteratorStack = new Stack(); public Stack getAxesIteratorStackStacks() { return m_axesIteratorStack; } public void setAxesIteratorStackStacks(Stack s) { m_axesIteratorStack = s; } /** * Push a TreeWalker on the stack. * * @param iter A sub-context AxesWalker. * @xsl.usage internal */ public final void pushSubContextList(SubContextList iter) { m_axesIteratorStack.push(iter); } /** * Pop the last pushed axes iterator. * @xsl.usage internal */ public final void popSubContextList() { m_axesIteratorStack.pop(); } /** * Get the current axes iterator, or return null if none. * * @return the sub-context node list. * @xsl.usage internal */ public SubContextList getSubContextList() { return m_axesIteratorStack.isEmpty() ? null : (SubContextList) m_axesIteratorStack.peek(); } /** * Get the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a> * as defined by the XSLT spec. * * @return the <a href="http://www.w3.org/TR/xslt#dt-current-node-list">current node list</a>. * @xsl.usage internal */ public com.sun.org.apache.xpath.internal.axes.SubContextList getCurrentNodeList() { return m_axesIteratorStack.isEmpty() ? null : (SubContextList) m_axesIteratorStack.elementAt(0); } //========================================================== // SECTION: Implementation of ExpressionContext interface //========================================================== /** * Get the current context node. * @return The current context node. */ public final int getContextNode() { return this.getCurrentNode(); } /** * Get the current context node list. * @return An iterator for the current context list, as * defined in XSLT. */ public final DTMIterator getContextNodes() { try { DTMIterator cnl = getContextNodeList(); if (null != cnl) return cnl.cloneWithReset(); else return null; // for now... this might ought to be an empty iterator. } catch (CloneNotSupportedException cnse) { return null; // error reporting? } } XPathExpressionContext expressionContext = new XPathExpressionContext(); /** * The the expression context for extensions for this context. * * @return An object that implements the ExpressionContext. */ public ExpressionContext getExpressionContext() { return expressionContext; } public class XPathExpressionContext implements ExpressionContext { /** * Return the XPathContext associated with this XPathExpressionContext. * Extensions should use this judiciously and only when special processing * requirements cannot be met another way. Consider requesting an enhancement * to the ExpressionContext interface to avoid having to call this method. * @return the XPathContext associated with this XPathExpressionContext. */ public XPathContext getXPathContext() { return XPathContext.this; } /** * Return the DTMManager object. Though XPathContext context extends * the DTMManager, it really is a proxy for the real DTMManager. If a * caller needs to make a lot of calls to the DTMManager, it is faster * if it gets the real one from this function. */ public DTMManager getDTMManager() { return m_dtmManager; } /** * Get the current context node. * @return The current context node. */ public org.w3c.dom.Node getContextNode() { int context = getCurrentNode(); return getDTM(context).getNode(context); } /** * Get the current context node list. * @return An iterator for the current context list, as * defined in XSLT. */ public org.w3c.dom.traversal.NodeIterator getContextNodes() { return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeIterator(getContextNodeList()); } /** * Get the error listener. * @return The registered error listener. */ public ErrorListener getErrorListener() { return XPathContext.this.getErrorListener(); } /** * Get the value of a node as a number. * @param n Node to be converted to a number. May be null. * @return value of n as a number. */ public double toNumber(org.w3c.dom.Node n) { // %REVIEW% You can't get much uglier than this... int nodeHandle = getDTMHandleFromNode(n); DTM dtm = getDTM(nodeHandle); XString xobj = (XString)dtm.getStringValue(nodeHandle); return xobj.num(); } /** * Get the value of a node as a string. * @param n Node to be converted to a string. May be null. * @return value of n as a string, or an empty string if n is null. */ public String toString(org.w3c.dom.Node n) { // %REVIEW% You can't get much uglier than this... int nodeHandle = getDTMHandleFromNode(n); DTM dtm = getDTM(nodeHandle); XMLString strVal = dtm.getStringValue(nodeHandle); return strVal.toString(); } /** * Get a variable based on it's qualified name. * @param qname The qualified name of the variable. * @return The evaluated value of the variable. * @throws javax.xml.transform.TransformerException */ public final XObject getVariableOrParam(com.sun.org.apache.xml.internal.utils.QName qname) throws javax.xml.transform.TransformerException { return m_variableStacks.getVariableOrParam(XPathContext.this, qname); } } /** * 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. * * 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; } /** * 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; } /** Push the RTFDTM's context mark, to allows discarding RTFs added after this * point. (If it doesn't exist we don't push, since we might still be able to * get away with not creating it. That requires that excessive pops be harmless.) * */ public void pushRTFContext() { m_last_pushed_rtfdtm.push(m_which_rtfdtm); if(null!=m_rtfdtm_stack) ((SAX2RTFDTM)(getRTFDTM())).pushRewindMark(); } /** Pop the RTFDTM's context mark. This discards any RTFs added after the last * mark was set. * * If there is no RTF DTM, there's nothing to pop so this * becomes a no-op. If pushes were issued before this was called, we count on * the fact that popRewindMark is defined such that overpopping just resets * to empty. * * Complicating factor: We need to handle the case of popping back to a previous * RTF DTM, if one of the weird produce-an-RTF-to-build-an-RTF cases arose. * Basically: If pop says this DTM is now empty, then return to the previous * if one exists, in whatever state we left it in. UGLY, but hopefully the * situation which forces us to consider this will arise exceedingly rarely. * */ public void popRTFContext() { int previous=m_last_pushed_rtfdtm.pop(); if(null==m_rtfdtm_stack) return; if(m_which_rtfdtm==previous) { if(previous>=0) // guard against none-active { boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(previous))).popRewindMark(); } } else while(m_which_rtfdtm!=previous) { // Empty each DTM before popping, so it's ready for reuse // _DON'T_ pop the previous, since it's still open (which is why we // stacked up more of these) and did not receive a mark. boolean isEmpty=((SAX2RTFDTM)(m_rtfdtm_stack.elementAt(m_which_rtfdtm))).popRewindMark(); --m_which_rtfdtm; } } /** * Gets DTMXRTreeFrag object if one has already been created. * Creates new DTMXRTreeFrag object and adds to m_DTMXRTreeFrags HashMap, * otherwise. * @param dtmIdentity * @return DTMXRTreeFrag */ public DTMXRTreeFrag getDTMXRTreeFrag(int dtmIdentity){ if(m_DTMXRTreeFrags == null){ m_DTMXRTreeFrags = new HashMap(); } if(m_DTMXRTreeFrags.containsKey(new Integer(dtmIdentity))){ return (DTMXRTreeFrag)m_DTMXRTreeFrags.get(new Integer(dtmIdentity)); }else{ final DTMXRTreeFrag frag = new DTMXRTreeFrag(dtmIdentity,this); m_DTMXRTreeFrags.put(new Integer(dtmIdentity),frag); return frag ; } } /** * Cleans DTMXRTreeFrag objects by removing references * to DTM and XPathContext objects. */ private final void releaseDTMXRTreeFrags(){ if(m_DTMXRTreeFrags == null){ return; } final Iterator iter = (m_DTMXRTreeFrags.values()).iterator(); while(iter.hasNext()){ DTMXRTreeFrag frag = (DTMXRTreeFrag)iter.next(); frag.destruct(); iter.remove(); } m_DTMXRTreeFrags = null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -