xpathmatcher.java

来自「JAVA 所有包」· Java 代码 · 共 520 行 · 第 1/2 页

JAVA
520
字号
/* * Copyright 2001, 2002,2004,2005 The Apache Software Foundation. *  * Licensed 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. */package com.sun.org.apache.xerces.internal.impl.xs.identity;import com.sun.org.apache.xerces.internal.impl.Constants;import com.sun.org.apache.xerces.internal.impl.xpath.XPath;import com.sun.org.apache.xerces.internal.util.IntStack;import com.sun.org.apache.xerces.internal.xni.QName;import com.sun.org.apache.xerces.internal.xni.XMLAttributes;import com.sun.org.apache.xerces.internal.xs.AttributePSVI;import com.sun.org.apache.xerces.internal.xs.ShortList;import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;import org.xml.sax.SAXException;/** * XPath matcher. * * @xerces.internal  * * @author Andy Clark, IBM * * @version $Id: XPathMatcher.java,v 1.2.6.1 2005/09/08 09:02:30 sunithareddy Exp $ */public class XPathMatcher {    //    // Constants    //    // debugging    /** Compile to true to debug everything. */    protected static final boolean DEBUG_ALL = false;    /** Compile to true to debug method callbacks. */    protected static final boolean DEBUG_METHODS = false || DEBUG_ALL;    /** Compile to true to debug important method callbacks. */    protected static final boolean DEBUG_METHODS2 = false || DEBUG_METHODS || DEBUG_ALL;    /** Compile to true to debug the <em>really</em> important methods. */    protected static final boolean DEBUG_METHODS3 = false || DEBUG_METHODS || DEBUG_ALL;    /** Compile to true to debug match. */    protected static final boolean DEBUG_MATCH = false || DEBUG_ALL;    /** Compile to true to debug step index stack. */    protected static final boolean DEBUG_STACK = false || DEBUG_ALL;    /** Don't touch this value unless you add more debug constants. */    protected static final boolean DEBUG_ANY = DEBUG_METHODS ||                                               DEBUG_METHODS2 ||                                               DEBUG_METHODS3 ||                                               DEBUG_MATCH ||                                               DEBUG_STACK;    // constants describing whether a match was made,    // and if so how.      // matched any way    protected static final int MATCHED = 1;    // matched on the attribute axis    protected static final int MATCHED_ATTRIBUTE = 3;    // matched on the descendant-or-self axixs    protected static final int MATCHED_DESCENDANT = 5;    // matched some previous (ancestor) node on the descendant-or-self-axis, but not this node    protected static final int MATCHED_DESCENDANT_PREVIOUS = 13;    //    // Data    //    /** XPath location path. */    private XPath.LocationPath[] fLocationPaths;    /** True if XPath has been matched. */    private int[] fMatched;    /** The matching string. */    protected Object fMatchedString;    /** Integer stack of step indexes. */    private IntStack[] fStepIndexes;    /** Current step. */    private int[] fCurrentStep;    /**     * No match depth. The value of this field will be zero while     * matching is successful for the given xpath expression.     */    private int [] fNoMatchDepth;        final QName fQName = new QName();    //    // Constructors    //    /**     * Constructs an XPath matcher that implements a document fragment     * handler.     *     * @param xpath   The xpath.     */    public XPathMatcher(XPath xpath) {        fLocationPaths = xpath.getLocationPaths();        fStepIndexes = new IntStack[fLocationPaths.length];        for(int i=0; i<fStepIndexes.length; i++) fStepIndexes[i] = new IntStack();        fCurrentStep = new int[fLocationPaths.length];        fNoMatchDepth = new int[fLocationPaths.length];        fMatched = new int[fLocationPaths.length];            } // <init>(XPath)    //    // Public methods    //    /**      * Returns value of first member of fMatched that     * is nonzero.       */    public boolean isMatched() {        // xpath has been matched if any one of the members of the union have matched.        for (int i=0; i < fLocationPaths.length; i++)             if (((fMatched[i] & MATCHED) == MATCHED)                     && ((fMatched[i] & MATCHED_DESCENDANT_PREVIOUS) != MATCHED_DESCENDANT_PREVIOUS)                     && ((fNoMatchDepth[i] == 0)                    || ((fMatched[i] & MATCHED_DESCENDANT) == MATCHED_DESCENDANT)))                 return true;        return false;    } // isMatched():int    //    // Protected methods    //    // a place-holder method; to be overridden by subclasses    // that care about matching element content.    protected void handleContent(XSTypeDefinition type, boolean nillable, Object value, short valueType, ShortList itemValueType) {     }     /**     * This method is called when the XPath handler matches the     * XPath expression. Subclasses can override this method to     * provide default handling upon a match.     */    protected void matched(Object actualValue, short valueType, ShortList itemValueType, boolean isNil) {        if (DEBUG_METHODS3) {            System.out.println(toString()+"#matched(\""+actualValue+"\")");        }    } // matched(String content, XSSimpleType val)    //    // ~XMLDocumentFragmentHandler methods    //    /**     * The start of the document fragment.     */    public void startDocumentFragment(){        if (DEBUG_METHODS) {            System.out.println(toString()+"#startDocumentFragment("+                               ")");        }        // reset state        fMatchedString = null;        for(int i = 0; i < fLocationPaths.length; i++) {            fStepIndexes[i].clear();            fCurrentStep[i] = 0;            fNoMatchDepth[i] = 0;            fMatched[i] = 0;        }    } // startDocumentFragment()    /**     * The start of an element. If the document specifies the start element     * by using an empty tag, then the startElement method will immediately     * be followed by the endElement method, with no intervening methods.     *     * @param element    The name of the element.     * @param attributes The element attributes.     *     * @throws SAXException Thrown by handler to signal an error.     */    public void startElement(QName element, XMLAttributes attributes){        if (DEBUG_METHODS2) {            System.out.println(toString()+"#startElement("+                               "element={"+element+"},"+                               "attributes=..."+attributes+                               ")");                             }        for(int i = 0; i < fLocationPaths.length; i++) {            // push context            int startStep = fCurrentStep[i];            fStepIndexes[i].push(startStep);            // try next xpath, if not matching            if ((fMatched[i] & MATCHED_DESCENDANT) == MATCHED || fNoMatchDepth[i] > 0) {                fNoMatchDepth[i]++;                continue;            }            if((fMatched[i] & MATCHED_DESCENDANT) == MATCHED_DESCENDANT) {                fMatched[i] = MATCHED_DESCENDANT_PREVIOUS;            }            if (DEBUG_STACK) {                System.out.println(toString()+": "+fStepIndexes[i]);            }            // consume self::node() steps            XPath.Step[] steps = fLocationPaths[i].steps;            while (fCurrentStep[i] < steps.length &&                    steps[fCurrentStep[i]].axis.type == XPath.Axis.SELF) {                if (DEBUG_MATCH) {                    XPath.Step step = steps[fCurrentStep[i]];                    System.out.println(toString()+" [SELF] MATCHED!");                }                fCurrentStep[i]++;            }            if (fCurrentStep[i] == steps.length) {                if (DEBUG_MATCH) {                    System.out.println(toString()+" XPath MATCHED!");                }                fMatched[i] = MATCHED;                continue;            }            // now if the current step is a descendant step, we let the next            // step do its thing; if it fails, we reset ourselves            // to look at this step for next time we're called.            // so first consume all descendants:            int descendantStep = fCurrentStep[i];            while(fCurrentStep[i] < steps.length && steps[fCurrentStep[i]].axis.type == XPath.Axis.DESCENDANT) {                if (DEBUG_MATCH) {                    XPath.Step step = steps[fCurrentStep[i]];                    System.out.println(toString()+" [DESCENDANT] MATCHED!");                }                fCurrentStep[i]++;            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?