📄 xmlnsdocumentscannerimpl.java
字号:
fAttributeQName.uri = uri; if (uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributePrefixUnbound", new Object[]{fElementQName.rawname,fAttributeQName.rawname,aprefix}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } fAttributes.setURI(i, uri); // checkDuplicates(fAttributeQName, fAttributes); } } if (length > 1) { QName name = fAttributes.checkDuplicatesNS(); if (name != null) { if (name.uri != null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributeNSNotUnique", new Object[]{fElementQName.rawname, name.localpart, name.uri}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } else { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "AttributeNotUnique", new Object[]{fElementQName.rawname, name.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } } } 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) { if(DEBUG) System.out.println("emptyElement = " + fElementQName); 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. fScanEndElement = true; //if (fBindNamespaces) { // 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> if(DEBUG) System.out.println("startElement = " + fElementQName); fDocumentHandler.startElement(fElementQName, fAttributes, null); } } if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +"<<< scanStartElement(): "+fEmptyElement); return fEmptyElement; } // scanStartElement():boolean /** * Scans an attribute. * <p> * <pre> * [41] Attribute ::= Name Eq AttValue * </pre> * <p> * <strong>Note:</strong> This method assumes that the next * character on the stream is the first character of the attribute * name. * <p> * <strong>Note:</strong> This method uses the fAttributeQName and * fQName variables. The contents of these variables will be * destroyed. * * @param attributes The attributes list for the scanned attribute. */ protected void scanAttribute(XMLAttributesImpl attributes) throws IOException, XNIException { if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanAttribute()"); // name fEntityScanner.scanQName(fAttributeQName); // equals fEntityScanner.skipSpaces(); if (!fEntityScanner.skipChar('=')) { reportFatalError("EqRequiredInAttribute", new Object[]{fCurrentElement.rawname,fAttributeQName.rawname}); } fEntityScanner.skipSpaces(); // content int attrIndex = 0 ; //REVISIT: one more case needs to be included: external PE and standalone is no boolean isVC = fHasExternalDTD && !fStandalone; // REVISIT: it seems that this function should not take attributes, and length //fTempString would store attribute value ///fTempString2 would store attribute non-normalized value //this function doesn't use 'attIndex'. We are adding the attribute later //after we have figured out that current attribute is not namespace declaration //since scanAttributeValue doesn't use attIndex parameter therefore we //can safely add the attribute later.. XMLString tmpStr = getString(); scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes, attrIndex, isVC); String value = null; //fTempString.toString(); // record namespace declarations if any. if (fBindNamespaces) { String localpart = fAttributeQName.localpart; String prefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; // when it's of form xmlns="..." or xmlns:prefix="...", // it's a namespace declaration. but prefix:xmlns="..." isn't. if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) { // get the internalized value of this attribute String uri = fSymbolTable.addSymbol(tmpStr.ch,tmpStr.offset,tmpStr.length); value = uri; // 1. "xmlns" can't be bound to any namespace if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 2. the namespace for "xmlns" can't be bound to any prefix if (uri == NamespaceContext.XMLNS_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXMLNS", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // 3. "xml" can't be bound to any other namespace than it's own if (localpart == XMLSymbols.PREFIX_XML) { if (uri != NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } // 4. the namespace for "xml" can't be bound to any other prefix else { if (uri ==NamespaceContext.XML_URI) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "CantBindXML", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING; //set it equal to XMLSymbols.PREFIX_XMLNS when namespace declaration // is of type xmlns = "..", in this case prefix = "" and localname = XMLSymbols.PREFIX_XMLNS //this special behavior is because of dependency on this behavior in DOM components if(prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS){ fAttributeQName.prefix = XMLSymbols.PREFIX_XMLNS; } // http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix // We should only report an error if there is a prefix, // that is, the local part is not "xmlns". -SG if (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "EmptyPrefixedAttName", new Object[]{fAttributeQName}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // check for duplicate prefix bindings if (((com.sun.org.apache.xerces.internal.util.NamespaceSupport) fNamespaceContext).containsPrefixInCurrentContext(prefix)) { reportFatalError("AttributeNotUnique", new Object[]{fCurrentElement.rawname, fAttributeQName.rawname}); } // declare prefix in context boolean declared = fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null); // check for duplicate xmlns declarations if (!declared) { // by convention, prefix == "xmlns" | "xml" // error if duplicate declaration if (fXmlnsDeclared) { reportFatalError("AttributeNotUnique", new Object[]{fCurrentElement.rawname, fAttributeQName.rawname}); } // xmlns declared fXmlnsDeclared = true; } //xerces internals (XSAttributeChecker) has dependency on namespace declaration returned //as part of XMLAttributes. //addition of namespace declaration to the attribute list is controlled by fNotAddNSDeclAsAttribute //feature. This is required in Stax where namespace declarations are not considered as attribute if(fNotAddNSDeclAsAttribute){ return ; } } } //add the attributes to the list of attributes if (fBindNamespaces) { attrIndex = attributes.getLength(); attributes.addAttributeNS(fAttributeQName, XMLSymbols.fCDATASymbol, null); } else { int oldLen = attributes.getLength(); attrIndex = attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null); // WFC: Unique Att Spec if (oldLen == attributes.getLength()) { reportFatalError("AttributeNotUnique", new Object[]{fCurrentElement.rawname, fAttributeQName.rawname}); } } attributes.setValue(attrIndex, value,tmpStr); //attributes.setNonNormalizedValue(attrIndex, fTempString2.toString()); //removing as we are not using non-normalized values . -Venu attributes.setSpecified(attrIndex, true); // attempt to bind attribute if (fAttributeQName.prefix != null) { attributes.setURI(attrIndex, fNamespaceContext.getURI(fAttributeQName.prefix)); } if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +"<<< scanAttribute()"); } // scanAttribute(XMLAttributes) /** Creates a content driver. */ protected Driver createContentDriver() { return new NSContentDriver(); } // createContentDriver():Driver /** * Driver to handle content scanning. */ protected final class NSContentDriver extends ContentDriver { /** * Scan for root element hook. This method is a hook for * subclasses to add code that handles scanning for the root * element. This method will also attempt to remove DTD validator * from the pipeline, if there is no DTD grammar. If DTD validator * is no longer in the pipeline bind namespaces in the scanner. * * * @return True if the caller should stop and return true which * allows the scanner to switch to a new scanning * driver. A return value of false indicates that * the content driver should continue as normal. */ protected boolean scanRootElementHook() throws IOException, XNIException { reconfigurePipeline(); if (scanStartElement()) { setScannerState(SCANNER_STATE_TRAILING_MISC); setDriver(fTrailingMiscDriver); return true; } return false; } // scanRootElementHook():boolean /** * Re-configures pipeline by removing the DTD validator * if no DTD grammar exists. If no validator exists in the * pipeline or there is no DTD grammar, namespace binding * is performed by the scanner in the enclosing class. */ private void reconfigurePipeline() { //fDTDValidator will be null in Stax mode if (fNamespaces && fDTDValidator == null) { fBindNamespaces = true; } else if (fNamespaces && !fDTDValidator.hasGrammar() ) { fBindNamespaces = true; fPerformValidation = fDTDValidator.validate(); // re-configure pipeline by removing DTDValidator XMLDocumentSource source = fDTDValidator.getDocumentSource(); XMLDocumentHandler handler = fDTDValidator.getDocumentHandler(); source.setDocumentHandler(handler); if (handler != null) handler.setDocumentSource(source); fDTDValidator.setDocumentSource(null); fDTDValidator.setDocumentHandler(null); } } // reconfigurePipeline() } } // class XMLNSDocumentScannerImpl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -