📄 xmldocumentfragmentscannerimpl.java
字号:
fMarkupDepth--; } // scanComment() //xxx value returned by this function may not remain valid if another event is scanned. public String getComment(){ return fContentBuffer.toString(); } void addElement(String rawname){ if(fElementPointer < ELEMENT_ARRAY_LENGTH){ //storing element raw name in a linear list of array fElementArray[fElementPointer] = rawname ; //storing elemnetPointer for particular element depth if(DEBUG_SKIP_ALGORITHM){ StringBuffer sb = new StringBuffer() ; sb.append(" Storing element information ") ; sb.append(" fElementPointer = " + fElementPointer) ; sb.append(" fElementRawname = " + fElementQName.rawname) ; sb.append(" fElementStack.fDepth = " + fElementStack.fDepth); System.out.println(sb.toString()) ; } //store pointer information only when element depth is less MAX_DEPTH_LIMIT if(fElementStack.fDepth < MAX_DEPTH_LIMIT){ short column = storePointerForADepth(fElementPointer); if(column > 0){ short pointer = getElementPointer((short)fElementStack.fDepth, (short)(column - 1) ); //identity comparison shouldn't take much time and we can rely on this //since its guaranteed to have same object id for same string. if(rawname == fElementArray[pointer]){ fShouldSkip = true ; fLastPointerLocation = pointer ; //reset the things and return. resetPointer((short)fElementStack.fDepth , column) ; fElementArray[fElementPointer] = null ; return ; }else{ fShouldSkip = false ; } } } fElementPointer++ ; } } void resetPointer(short depth, short column){ fPointerInfo[depth] [column] = (short)0; } //returns column information at which pointer was stored. short storePointerForADepth(short elementPointer){ short depth = (short) fElementStack.fDepth ; //Stores element pointer locations at particular depth , only 4 pointer locations //are stored at particular depth for now. for(short i = 0 ; i < MAX_POINTER_AT_A_DEPTH ; i++){ if(canStore(depth, i)){ fPointerInfo[depth][i] = elementPointer ; if(DEBUG_SKIP_ALGORITHM){ StringBuffer sb = new StringBuffer() ; sb.append(" Pointer information ") ; sb.append(" fElementPointer = " + fElementPointer) ; sb.append(" fElementStack.fDepth = " + fElementStack.fDepth); sb.append(" column = " + i ) ; System.out.println(sb.toString()) ; } return i; } //else //pointer was not stored because we reached the limit } return -1 ; } boolean canStore(short depth, short column){ //colum = 0 , means first element at particular depth //column = 1, means second element at particular depth // calle should make sure that it doesn't call for value outside allowed co-ordinates return fPointerInfo[depth][column] == 0 ? true : false ; } short getElementPointer(short depth, short column){ //colum = 0 , means first element at particular depth //column = 1, means second element at particular depth // calle should make sure that it doesn't call for value outside allowed co-ordinates return fPointerInfo[depth][column] ; } //this function assumes that string passed is not null and skips //the following string from the buffer this makes sure boolean skipFromTheBuffer(String rawname) throws IOException{ if(fEntityScanner.skipString(rawname)){ char c = (char)fEntityScanner.peekChar() ; //If the start element was completely skipped we should encounter either ' '(space), //or '/' (in case of empty element) or '>' if( c == ' ' || c == '/' || c == '>'){ fElementRawname = rawname ; return true ; } else{ return false; } } else return false ; } boolean skipQElement(String rawname) throws IOException{ final int c = fEntityScanner.getChar(rawname.length()); //if this character is still valid element name -- this means string can't match if(XMLChar.isName(c)){ return false; }else{ return fEntityScanner.skipString(rawname); } } protected boolean skipElement() throws IOException { if(!fShouldSkip) return false ; if(fLastPointerLocation != 0){ //Look at the next element stored in the array list.. we might just get a match. String rawname = fElementArray[fLastPointerLocation + 1] ; if(rawname != null && skipFromTheBuffer(rawname)){ fLastPointerLocation++ ; if(DEBUG_SKIP_ALGORITHM){ System.out.println("Element " + fElementRawname + " was SKIPPED at pointer location = " + fLastPointerLocation); } return true ; } else{ //reset it back to zero... we haven't got the correct subset yet. fLastPointerLocation = 0 ; } } //xxx: we can put some logic here as from what column it should start looking //for now we always start at 0 //fallback to tolerant algorithm, it would look for differnt element stored at different //depth and get us the pointer location. return fShouldSkip && skipElement((short)0); } //start of the column at which it should try searching boolean skipElement(short column) throws IOException { short depth = (short)fElementStack.fDepth ; if(depth > MAX_DEPTH_LIMIT){ return fShouldSkip = false ; } for(short i = column ; i < MAX_POINTER_AT_A_DEPTH ; i++){ short pointer = getElementPointer(depth , i ) ; if(pointer == 0){ return fShouldSkip = false ; } if(fElementArray[pointer] != null && skipFromTheBuffer(fElementArray[pointer])){ if(DEBUG_SKIP_ALGORITHM){ System.out.println(); System.out.println("Element " + fElementRawname + " was SKIPPED at depth = " + fElementStack.fDepth + " column = " + column ); System.out.println(); } fLastPointerLocation = pointer ; return fShouldSkip = true ; } } return fShouldSkip = false ; } /** * Scans a start element. This method will handle the binding of * namespace information and notifying the handler of the start * of the element. * <p> * <pre> * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' * [40] STag ::= '<' Name (S Attribute)* S? '>' * </pre> * <p> * <strong>Note:</strong> This method assumes that the leading * '<' character has been consumed. * <p> * <strong>Note:</strong> This method uses the fElementQName and * fAttributes variables. The contents of these variables will be * destroyed. The caller should copy important information out of * these variables before calling this method. * NB: Content in fAttributes is valid only till the state of the parser is XMLEvent.START_ELEMENT * * @return True if element is empty. (i.e. It matches * production [44]. */ // fElementQName will have the details of element just read.. // fAttributes will have the details of all the attributes. protected boolean scanStartElement() throws IOException, XNIException { if (DEBUG_START_END_ELEMENT) System.out.println( this.getClass().toString() + ">>> scanStartElement()"); //when skipping is true and no more elements should be added if(fSkip && !fAdd){ //get the stored element -- if everything goes right this should match the //token in the buffer QName name = fElementStack.getNext(); if(DEBUG_SKIP_ALGORITHM){ System.out.println("Trying to skip String = " + name.rawname); } //Be conservative -- if skipping fails -- stop. fSkip = fEntityScanner.skipString(name.rawname); if(fSkip){ if(DEBUG_SKIP_ALGORITHM){ System.out.println("Element SUCESSFULLY skipped = " + name.rawname); } fElementStack.push(); fElementQName = name; }else{ //if skipping fails reposition the stack or fallback to normal way of processing fElementStack.reposition(); if(DEBUG_SKIP_ALGORITHM){ System.out.println("Element was NOT skipped, REPOSITIONING stack" ); } } } //we are still at the stage of adding elements //the elements were not matched or //fSkip is not set to true if(!fSkip || fAdd){ //get the next element from the stack fElementQName = fElementStack.nextElement(); // name if (fNamespaces) { fEntityScanner.scanQName(fElementQName); } else { String name = fEntityScanner.scanName(); fElementQName.setValues(null, name, name, null); } if(DEBUG)System.out.println("Element scanned in start element is " + fElementQName.toString()); if(DEBUG_SKIP_ALGORITHM){ if(fAdd){ System.out.println("Elements are being ADDED -- elemet added is = " + fElementQName.rawname + " at count = " + fElementStack.fCount); } } } //when the elements are being added , we need to check if we are set for skipping the elements if(fAdd){ //this sets the value of fAdd variable fElementStack.matchElement(fElementQName); } //xxx: We dont need another pointer, fCurrentElement, we can use fElementQName fCurrentElement = fElementQName; String rawname = fElementQName.rawname; fEmptyElement = false; fAttributes.removeAllAttributes(); if(!seekCloseOfStartTag()){ fReadingAttributes = true; fAttributeCacheUsedCount =0; fStringBufferIndex =0; fAddDefaultAttr = true; do { scanAttribute(fAttributes); if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, XMLErrorReporter.SEVERITY_FATAL_ERROR ); } } while (!seekCloseOfStartTag()); fReadingAttributes=false; } if (fEmptyElement) { //decrease the markup depth.. fMarkupDepth--; // check that this element was opened in the same entity if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { reportFatalError("ElementEntityMismatch", new Object[]{fCurrentElement.rawname}); } // call handler if (fDocumentHandler != null) { fDocumentHandler.emptyElement(fElementQName, fAttributes, null); } //We should not be popping out the context here in endELement becaause the namespace context is still //valid when parser is at the endElement state. //if (fNamespaces) { // fNamespaceContext.popContext(); //} //pop the element off the stack.. fElementStack.popElement(); } else { if(dtdGrammarUtil != null) dtdGrammarUtil.startElement(fElementQName, fAttributes); if(fDocumentHandler != null){ //complete element and attributes are traversed in this function so we can send a callback //here. //<strong>we shouldn't be sending callback in scanDocument()</strong> fDocumentHandler.startElement(fElementQName, fAttributes, null); } } if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() + "<<< scanStartElement(): "+fEmptyElement); return fEmptyElement; } // scanStartElement():boolean /** * Looks for the close of start tag, i.e. if it finds '>' or '/>' * Characters are consumed. */ protected boolean seekCloseOfStartTag() throws IOException, XNIException { // spaces boolean sawSpace = fEntityScanner.skipSpaces(); // end tag? final int c = fEntityScanner.peekChar(); if (c == '>') { fEntityScanner.scanChar(); return true; } else if (c == '/') { fEntityScanner.scanChar(); if (!fEntityScanner.skipChar('>')) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -