| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * Copyright (c) 1999-2000 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xerces" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache\@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation, and was |
| * originally based on software copyright (c) 1999, International |
| * Business Machines, Inc., http://www.ibm.com . For more information |
| * on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| /** |
| * This file contains code to build the DOM tree. It registers a document |
| * handler with the scanner. In these handler methods, appropriate DOM nodes |
| * are created and added to the DOM tree. |
| * |
| * $Id$ |
| * |
| */ |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // Includes |
| // --------------------------------------------------------------------------- |
| #include <sax/EntityResolver.hpp> |
| #include <sax/ErrorHandler.hpp> |
| #include <sax/SAXParseException.hpp> |
| #include <framework/XMLNotationDecl.hpp> |
| #include <util/IOException.hpp> |
| #include <internal/XMLScanner.hpp> |
| #include <validators/DTD/DTDValidator.hpp> |
| #include <parsers/DOMParser.hpp> |
| #include <dom/ElementImpl.hpp> |
| #include <dom/AttrImpl.hpp> |
| #include <dom/TextImpl.hpp> |
| #include <dom/DocumentImpl.hpp> |
| #include <dom/DocumentTypeImpl.hpp> |
| #include <dom/EntityImpl.hpp> |
| #include <dom/NotationImpl.hpp> |
| #include <dom/NamedNodeMapImpl.hpp> |
| #include <dom/NodeIDMap.hpp> |
| |
| #include <validators/DTD/ContentSpecNode.hpp> |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Constructors and Destructor |
| // --------------------------------------------------------------------------- |
| DOMParser::DOMParser(XMLValidator* const valToAdopt) : |
| |
| fErrorHandler(0) |
| , fEntityResolver(0) |
| , fExpandEntityReferences(false) |
| , fToCreateXMLDeclTypeNode(false) |
| , fIncludeIgnorableWhitespace(true) |
| , fNodeStack(0) |
| , fScanner(0) |
| , fOldDocTypeHandler(0) |
| , fValidator(valToAdopt) |
| { |
| |
| // Create the validator if one was not provided |
| if (!fValidator) |
| fValidator = new DTDValidator; |
| |
| //If the user already registered the doctypehandler then chain it |
| fOldDocTypeHandler = ((DTDValidator*)fValidator)->getDocTypeHandler(); |
| |
| //register the new doctypehandler |
| ((DTDValidator*)fValidator)->setDocTypeHandler(this); |
| // |
| // Create a scanner and tell it what validator to use. Then set us |
| // as the document event handler so we can fill the DOM document. |
| // |
| fScanner = new XMLScanner(fValidator); |
| fScanner->setDocHandler(this); |
| |
| fNodeStack = new ValueStackOf<DOM_Node>(64); |
| this->reset(); |
| |
| |
| } |
| |
| |
| DOMParser::~DOMParser() |
| { |
| delete fNodeStack; |
| delete fScanner; |
| delete fValidator; |
| } |
| |
| |
| void DOMParser::reset() |
| { |
| // |
| // Note: DOM Documents are reference counted. Doing this assignment |
| // will cause the old one to go away unless application code is also |
| // holding a reference to it. |
| // |
| fDocument = DOM_Document::createDocument(); |
| resetDocType(); |
| |
| fCurrentParent = 0; |
| fCurrentNode = 0; |
| fParseInProgress = false; |
| fWithinElement = false; |
| fNodeStack->removeAllElements(); |
| }; |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Getter methods |
| // --------------------------------------------------------------------------- |
| const XMLValidator& DOMParser::getValidator() const |
| { |
| return *fValidator; |
| } |
| |
| bool DOMParser::getDoNamespaces() const |
| { |
| return fScanner->getDoNamespaces(); |
| } |
| |
| bool DOMParser::getExitOnFirstFatalError() const |
| { |
| return fScanner->getExitOnFirstFatal(); |
| } |
| |
| DOMParser::ValSchemes DOMParser::getValidationScheme() const |
| { |
| const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme(); |
| |
| if (scheme == XMLScanner::Val_Always) |
| return Val_Always; |
| else if (scheme == XMLScanner::Val_Never) |
| return Val_Never; |
| |
| return Val_Auto; |
| } |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Setter methods |
| // --------------------------------------------------------------------------- |
| void DOMParser::setDoNamespaces(const bool newState) |
| { |
| fScanner->setDoNamespaces(newState); |
| } |
| |
| void DOMParser::setErrorHandler(ErrorHandler* const handler) |
| { |
| fErrorHandler = handler; |
| if (fErrorHandler) |
| { |
| fScanner->setErrorReporter(this); |
| fValidator->setErrorReporter(this); |
| } |
| else |
| { |
| fScanner->setErrorReporter(0); |
| fValidator->setErrorReporter(0); |
| } |
| } |
| |
| void DOMParser::setEntityResolver(EntityResolver* const handler) |
| { |
| fEntityResolver = handler; |
| if (fEntityResolver) |
| fScanner->setEntityHandler(this); |
| else |
| fScanner->setEntityHandler(0); |
| } |
| |
| void DOMParser::setExitOnFirstFatalError(const bool newState) |
| { |
| fScanner->setExitOnFirstFatal(newState); |
| } |
| |
| void DOMParser::setValidationScheme(const ValSchemes newScheme) |
| { |
| if (newScheme == Val_Never) |
| fScanner->setValidationScheme(XMLScanner::Val_Never); |
| else if (newScheme == Val_Always) |
| fScanner->setValidationScheme(XMLScanner::Val_Always); |
| else |
| fScanner->setValidationScheme(XMLScanner::Val_Auto); |
| } |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Parsing methods |
| // --------------------------------------------------------------------------- |
| void DOMParser::parse(const InputSource& source, const bool reuseValidator) |
| { |
| // Avoid multiple entrance |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| try |
| { |
| fParseInProgress = true; |
| fScanner->scanDocument(source, reuseValidator); |
| fParseInProgress = false; |
| } |
| |
| catch(...) |
| { |
| fParseInProgress = false; |
| throw; |
| } |
| } |
| |
| void DOMParser::parse(const XMLCh* const systemId, const bool reuseValidator) |
| { |
| // Avoid multiple entrance |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| try |
| { |
| fParseInProgress = true; |
| fScanner->scanDocument(systemId, reuseValidator); |
| fParseInProgress = false; |
| } |
| |
| catch(...) |
| { |
| fParseInProgress = false; |
| throw; |
| } |
| } |
| |
| void DOMParser::parse(const char* const systemId, const bool reuseValidator) |
| { |
| // Avoid multiple entrance |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| try |
| { |
| fParseInProgress = true; |
| fScanner->scanDocument(systemId, reuseValidator); |
| fParseInProgress = false; |
| } |
| |
| catch(...) |
| { |
| fParseInProgress = false; |
| throw; |
| } |
| } |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Progressive parse methods |
| // --------------------------------------------------------------------------- |
| bool DOMParser::parseFirst( const XMLCh* const systemId |
| , XMLPScanToken& toFill |
| , const bool reuseValidator) |
| { |
| // |
| // Avoid multiple entrance. We cannot enter here while a regular parse |
| // is in progress. |
| // |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| return fScanner->scanFirst(systemId, toFill, reuseValidator); |
| } |
| |
| bool DOMParser::parseFirst( const char* const systemId |
| , XMLPScanToken& toFill |
| , const bool reuseValidator) |
| { |
| // |
| // Avoid multiple entrance. We cannot enter here while a regular parse |
| // is in progress. |
| // |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| return fScanner->scanFirst(systemId, toFill, reuseValidator); |
| } |
| |
| bool DOMParser::parseFirst( const InputSource& source |
| , XMLPScanToken& toFill |
| , const bool reuseValidator) |
| { |
| // |
| // Avoid multiple entrance. We cannot enter here while a regular parse |
| // is in progress. |
| // |
| if (fParseInProgress) |
| ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); |
| |
| return fScanner->scanFirst(source, toFill, reuseValidator); |
| } |
| |
| bool DOMParser::parseNext(XMLPScanToken& token) |
| { |
| return fScanner->scanNext(token); |
| } |
| |
| void DOMParser::parseReset(XMLPScanToken& token) |
| { |
| // Reset the scanner, and then reset the parser |
| fScanner->scanReset(token); |
| reset(); |
| } |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Implementation of the XMLErrorReporter interface |
| // --------------------------------------------------------------------------- |
| void DOMParser::error( const unsigned int code |
| , const XMLCh* const msgDomain |
| , const XMLErrorReporter::ErrTypes errType |
| , const XMLCh* const errorText |
| , const XMLCh* const systemId |
| , const XMLCh* const publicId |
| , const unsigned int lineNum |
| , const unsigned int colNum) |
| { |
| SAXParseException toThrow = SAXParseException |
| ( |
| errorText |
| , publicId |
| , systemId |
| , lineNum |
| , colNum |
| ); |
| |
| // |
| // If there is an error handler registered, call it, otherwise ignore |
| // all but the fatal errors. |
| // |
| if (!fErrorHandler) |
| { |
| if (errType == XMLErrorReporter::ErrType_Fatal) |
| throw toThrow; |
| return; |
| } |
| |
| if (errType == XMLErrorReporter::ErrType_Warning) |
| fErrorHandler->warning(toThrow); |
| else if (errType >= XMLErrorReporter::ErrType_Fatal) |
| fErrorHandler->fatalError(toThrow); |
| else |
| fErrorHandler->error(toThrow); |
| } |
| |
| void DOMParser::resetErrors() |
| { |
| } |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Implementation of XMLEntityHandler interface |
| // --------------------------------------------------------------------------- |
| InputSource* |
| DOMParser::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId) |
| { |
| // |
| // Just map it to the SAX entity resolver. If there is not one installed, |
| // return a null pointer to cause the default resolution. |
| // |
| if (fEntityResolver) |
| return fEntityResolver->resolveEntity(publicId, systemId); |
| return 0; |
| } |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Implementation of XMLDocumentHandler interface |
| // --------------------------------------------------------------------------- |
| void DOMParser::docCharacters( const XMLCh* const chars |
| , const unsigned int length |
| , const bool cdataSection) |
| { |
| // Ignore chars outside of content |
| if (!fWithinElement) |
| return; |
| |
| if (cdataSection == true) |
| { |
| DOM_CDATASection node = fDocument.createCDATASection |
| ( |
| DOMString(chars, length) |
| ); |
| fCurrentParent.appendChild(node); |
| fCurrentNode = node; |
| } |
| else |
| { |
| if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE) |
| { |
| DOM_Text node = (DOM_Text&)fCurrentNode; |
| node.appendData(DOMString(chars, length)); |
| } |
| else |
| { |
| DOM_Text node = fDocument.createTextNode(DOMString(chars, length)); |
| //If the node type is entityRef then set the readOnly flag to false before appending node |
| bool oldReadFlag; |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| oldReadFlag = fCurrentParent.fImpl->readOnly(); |
| fCurrentParent.fImpl->readOnly(false); |
| } |
| |
| fCurrentParent.appendChild(node); |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| fCurrentParent.fImpl->readOnly(oldReadFlag); |
| } |
| fCurrentNode = node; |
| } |
| } |
| } |
| |
| |
| void DOMParser::docComment(const XMLCh* const comment) |
| { |
| DOM_Comment dcom = fDocument.createComment(comment); |
| fCurrentParent.appendChild(dcom); |
| fCurrentNode = dcom; |
| } |
| |
| |
| void DOMParser::docPI( const XMLCh* const target |
| , const XMLCh* const data) |
| { |
| DOM_ProcessingInstruction pi = fDocument.createProcessingInstruction |
| ( |
| target |
| , data |
| ); |
| fCurrentParent.appendChild(pi); |
| fCurrentNode = pi; |
| } |
| |
| |
| void DOMParser::endEntityReference(const XMLEntityDecl& entDecl) |
| { |
| if (fExpandEntityReferences == true) |
| { |
| fCurrentParent = fNodeStack->pop(); |
| fCurrentNode = fCurrentParent; |
| } |
| } |
| |
| |
| void DOMParser::endElement( const XMLElementDecl& elemDecl |
| , const unsigned int urlId |
| , const bool isRoot) |
| { |
| fCurrentNode = fCurrentParent; |
| fCurrentParent = fNodeStack->pop(); |
| |
| // If we've hit the end of content, clear the flag |
| if (fNodeStack->empty()) |
| fWithinElement = false; |
| } |
| |
| |
| void DOMParser::ignorableWhitespace(const XMLCh* const chars |
| , const unsigned int length |
| , const bool cdataSection) |
| { |
| // Ignore chars before the root element |
| if (!fWithinElement || !fIncludeIgnorableWhitespace) |
| return; |
| |
| if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE) |
| { |
| DOM_Text node = (DOM_Text&)fCurrentNode; |
| node.appendData(DOMString(chars, length)); |
| } |
| else |
| { |
| DOM_Text node = fDocument.createTextNode(DOMString(chars, length)); |
| TextImpl *text = (TextImpl *) node.fImpl; |
| text -> setIgnorableWhitespace(true); |
| //If the node type is entityRef then set the readOnly flag to false before appending node |
| bool oldReadFlag; |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| oldReadFlag = fCurrentParent.fImpl->readOnly(); |
| fCurrentParent.fImpl->readOnly(false); |
| } |
| |
| fCurrentParent.appendChild(node); |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| fCurrentParent.fImpl->readOnly(oldReadFlag); |
| } |
| |
| fCurrentNode = node; |
| } |
| } |
| |
| |
| void DOMParser::resetDocument() |
| { |
| // |
| // The reset methods are called before a new parse event occurs. |
| // Reset this parsers state to clear out anything that may be left |
| // from a previous use, in particular the DOM document itself. |
| // |
| this->reset(); |
| } |
| |
| |
| void DOMParser::startDocument() |
| { |
| // Just set the document as the current parent and current node |
| fCurrentParent = fDocument; |
| fCurrentNode = fDocument; |
| } |
| |
| |
| void DOMParser::startElement(const XMLElementDecl& elemDecl |
| , const unsigned int urlId |
| , const XMLCh* const elemPrefix |
| , const RefVectorOf<XMLAttr>& attrList |
| , const unsigned int attrCount |
| , const bool isEmpty |
| , const bool isRoot) |
| { |
| DOM_Element elem; |
| DocumentImpl *docImpl = (DocumentImpl *)fDocument.fImpl; |
| |
| if (fScanner -> getDoNamespaces()) { //DOM Level 2, doNamespaces on |
| unsigned int globalNSid = fValidator -> getGlobalNamespaceId(); |
| XMLBuffer buf; |
| DOMString namespaceURI = 0; |
| if (urlId != globalNSid) { //TagName has a prefix |
| fValidator -> getURIText(urlId, buf); //get namespaceURI |
| namespaceURI = DOMString(buf.getRawBuffer()); |
| } |
| elem = fDocument.createElementNS(namespaceURI, elemDecl.getFullName()); |
| ElementImpl *elemImpl = (ElementImpl *) elem.fImpl; |
| for (unsigned int index = 0; index < attrCount; ++index) { |
| static const XMLCh XMLNS[] = { |
| chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull |
| }; |
| const XMLAttr* oneAttrib = attrList.elementAt(index); |
| unsigned int attrURIId = oneAttrib -> getURIId(); |
| namespaceURI = 0; |
| if (!XMLString::compareString(oneAttrib -> getName(), XMLNS)) //for xmlns=... |
| attrURIId = fValidator -> getXMLNSNamespaceId(); |
| if (attrURIId != globalNSid) { //TagName has a prefix |
| fValidator -> getURIText(attrURIId, buf); //get namespaceURI |
| namespaceURI = DOMString(buf.getRawBuffer()); |
| } |
| AttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(), |
| oneAttrib -> getValue()); |
| |
| // Attributes of type ID. If this is one, add it to the hashtable of IDs |
| // that is constructed for use by GetElementByID(). |
| // |
| if (oneAttrib->getType()==XMLAttDef::ID) |
| { |
| if (docImpl->fNodeIDMap == 0) |
| docImpl->fNodeIDMap = new NodeIDMap(500); |
| docImpl->fNodeIDMap->add(attr); |
| attr->idAttr(true); |
| } |
| |
| attr->setSpecified(oneAttrib->getSpecified()); |
| } |
| } else { //DOM Level 1 |
| elem = fDocument.createElement(elemDecl.getFullName()); |
| ElementImpl *elemImpl = (ElementImpl *) elem.fImpl; |
| for (unsigned int index = 0; index < attrCount; ++index) { |
| const XMLAttr* oneAttrib = attrList.elementAt(index); |
| AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue()); |
| attr->setSpecified(oneAttrib->getSpecified()); |
| |
| // Attributes of type ID. If this is one, add it to the hashtable of IDs |
| // that is constructed for use by GetElementByID(). |
| // |
| if (oneAttrib->getType()==XMLAttDef::ID) |
| { |
| if (docImpl->fNodeIDMap == 0) |
| docImpl->fNodeIDMap = new NodeIDMap(500); |
| docImpl->fNodeIDMap->add(attr); |
| attr->idAttr(true); |
| } |
| |
| } |
| } |
| |
| //If the node type is entityRef then set the readOnly flag to false before appending node |
| bool oldReadFlag; |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| oldReadFlag = fCurrentParent.fImpl->readOnly(); |
| fCurrentParent.fImpl->readOnly(false); |
| } |
| |
| fCurrentParent.appendChild(elem); |
| if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) { |
| fCurrentParent.fImpl->readOnly(oldReadFlag); |
| } |
| |
| fNodeStack->push(fCurrentParent); |
| fCurrentParent = elem; |
| fCurrentNode = elem; |
| fWithinElement = true; |
| |
| // If an empty element, do end right now (no endElement() will be called) |
| if (isEmpty) |
| endElement(elemDecl, urlId, isRoot); |
| } |
| |
| |
| void DOMParser::startEntityReference(const XMLEntityDecl& entDecl) |
| { |
| if (fExpandEntityReferences == true) |
| { |
| DOMString entName(entDecl.getName()); |
| DOM_EntityReference er = fDocument.createEntityReference(entName); |
| fCurrentParent.appendChild(er); |
| fNodeStack->push(fCurrentParent); |
| fCurrentParent = er; |
| fCurrentNode = er; |
| |
| //this entityRef needs to be stored in Entity map too. |
| EntityImpl* entity = (EntityImpl*)fDocumentType->entities->getNamedItem(entName); |
| entity->setEntityRef((EntityReferenceImpl*)er.fImpl); |
| fDocumentType->entities->setNamedItem(entity); |
| } |
| } |
| |
| |
| void DOMParser::XMLDecl(const XMLCh* const version |
| , const XMLCh* const encoding |
| , const XMLCh* const standalone |
| , const XMLCh* const actualEncStr) |
| { |
| //This is a non-standard extension to creating XMLDecl type nodes and attching to DOM Tree |
| // currently this flag it set to false unless user explicitly asks for it |
| // Needs to be revisited after W3C specs are laid out on this issue. |
| |
| if (fToCreateXMLDeclTypeNode) { |
| |
| DOMString ver(version); |
| DOMString enc(encoding); |
| DOMString std(standalone); |
| DOM_XMLDecl xmlDecl = fDocument.createXMLDecl(ver, enc, std); |
| |
| fCurrentParent.appendChild(xmlDecl); |
| } |
| } |
| |
| |
| |
| // --------------------------------------------------------------------------- |
| // DOMParser: Deprecated methods |
| // --------------------------------------------------------------------------- |
| bool DOMParser::getDoValidation() const |
| { |
| // |
| // We don't want to tie the public parser classes to the enum used |
| // by the scanner, so we use a separate one and map. |
| // |
| // DON'T mix the new and old methods!! |
| // |
| const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme(); |
| if (scheme == XMLScanner::Val_Always) |
| return true; |
| return false; |
| } |
| |
| void DOMParser::setDoValidation(const bool newState) |
| { |
| fScanner->setDoValidation |
| ( |
| newState ? XMLScanner::Val_Always : XMLScanner::Val_Never |
| ); |
| } |
| |
| //doctypehandler interfaces |
| void DOMParser::attDef |
| ( |
| const DTDElementDecl& elemDecl |
| , const DTDAttDef& attDef |
| , const bool ignoring |
| ) |
| { |
| if(fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->attDef(elemDecl,attDef, ignoring ); |
| } |
| |
| if (fDocumentType->isIntSubsetReading()) |
| { |
| DOMString attString; |
| if (elemDecl.hasAttDefs()) |
| { |
| attString.appendData(chOpenAngle); |
| attString.appendData(chBang); |
| attString.appendData(XMLUni::fgAttListString); |
| attString.appendData(chSpace); |
| attString.appendData(elemDecl.getFullName()); |
| |
| attString.appendData(chSpace); |
| attString.appendData(attDef.getFullName()); |
| |
| // Get the type and display it |
| const XMLAttDef::AttTypes type = attDef.getType(); |
| switch(type) |
| { |
| case XMLAttDef::CData : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgCDATAString); |
| break; |
| case XMLAttDef::ID : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgIDString); |
| break; |
| case XMLAttDef::IDRef : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgIDRefString); |
| break; |
| case XMLAttDef::IDRefs : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgIDRefsString); |
| break; |
| case XMLAttDef::Entity : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgEntityString); |
| break; |
| case XMLAttDef::Entities : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgEntitiesString); |
| break; |
| case XMLAttDef::NmToken : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgNmTokenString); |
| break; |
| case XMLAttDef::NmTokens : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgNmTokensString); |
| break; |
| |
| case XMLAttDef::Notation : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgNotationString); |
| break; |
| |
| case XMLAttDef::Enumeration : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgEnumerationString); |
| break; |
| } |
| //get te default types of the attlist |
| const XMLAttDef::DefAttTypes def = attDef.getDefaultType(); |
| switch(def) |
| { |
| case XMLAttDef::Required : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgRequiredString); |
| break; |
| case XMLAttDef::Implied : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgImpliedString); |
| break; |
| case XMLAttDef::Fixed : |
| attString.appendData(chSpace); |
| attString.appendData(XMLUni::fgFixedString); |
| break; |
| } |
| attString.appendData(chCloseAngle); |
| fDocumentType->internalSubset.appendData(attString); |
| } |
| } |
| } |
| |
| void DOMParser::doctypeComment |
| ( |
| const XMLCh* const comment |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->doctypeComment(comment); |
| } |
| if (fDocumentType->isIntSubsetReading()) |
| { |
| if (comment != 0) |
| { |
| DOMString comString; |
| comString.appendData(XMLUni::fgCommentString); |
| comString.appendData(chSpace); |
| comString.appendData(comment); |
| comString.appendData(chSpace); |
| comString.appendData(chDash); |
| comString.appendData(chDash); |
| comString.appendData(chCloseAngle); |
| fDocumentType->internalSubset.appendData(comString); |
| } |
| } |
| } |
| |
| void DOMParser::doctypeDecl |
| ( |
| const DTDElementDecl& elemDecl |
| , const XMLCh* const publicId |
| , const XMLCh* const systemId |
| , const bool hasIntSubset |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->doctypeDecl(elemDecl, publicId, systemId, hasIntSubset); |
| } |
| |
| DOM_DocumentType dt; |
| dt = fDocument.getImplementation().createDocumentType(elemDecl.getFullName(), publicId, systemId); |
| fDocumentType = (DocumentTypeImpl*)dt.fImpl; |
| ((DocumentImpl*)fDocument.fImpl)->setDocumentType(fDocumentType); |
| |
| populateDocumentType(); // Add the entities and notations to this DocType. |
| |
| } |
| |
| void DOMParser::doctypePI |
| ( |
| const XMLCh* const target |
| , const XMLCh* const data |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->doctypePI(target, data); |
| } |
| if (fDocumentType->isIntSubsetReading()) |
| { |
| //add these chars to internalSubset variable |
| DOMString pi; |
| pi.appendData(chOpenAngle); |
| pi.appendData(chQuestion); |
| pi.appendData(target); |
| pi.appendData(chSpace); |
| pi.appendData(data); |
| pi.appendData(chQuestion); |
| pi.appendData(chCloseAngle); |
| |
| fDocumentType->internalSubset.appendData(pi); |
| } |
| |
| } |
| |
| |
| void DOMParser::doctypeWhitespace |
| ( |
| const XMLCh* const chars |
| , const unsigned int length |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->doctypeWhitespace(chars, length); |
| } |
| |
| if (fDocumentType->isIntSubsetReading()) |
| fDocumentType->internalSubset.appendData(chars); |
| } |
| |
| void DOMParser::elementDecl |
| ( |
| const DTDElementDecl& decl |
| , const bool isIgnored |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->elementDecl(decl, isIgnored); |
| } |
| if (fDocumentType->isIntSubsetReading()) |
| { |
| DOMString elemDecl; |
| |
| elemDecl.appendData(chOpenAngle); |
| elemDecl.appendData(chBang); |
| elemDecl.appendData(XMLUni::fgElemString); |
| elemDecl.appendData(chSpace); |
| elemDecl.appendData(decl.getFullName()); |
| |
| //get the ContentSpec information |
| const XMLCh* contentModel = decl.getFormattedContentModel(*fValidator); |
| if (contentModel != 0) { |
| elemDecl.appendData(chSpace); |
| elemDecl.appendData(contentModel); |
| } |
| |
| elemDecl.appendData(chCloseAngle); |
| fDocumentType->internalSubset.appendData(elemDecl); |
| } |
| } |
| |
| void DOMParser::endAttList |
| ( |
| const DTDElementDecl& elemDecl |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->endAttList(elemDecl); |
| } |
| } |
| |
| void DOMParser::endIntSubset() |
| { |
| fDocumentType->intSubsetReading = false; |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->endIntSubset(); |
| } |
| } |
| |
| void DOMParser::endExtSubset() |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->endExtSubset(); |
| } |
| } |
| |
| void DOMParser::entityDecl |
| ( |
| const DTDEntityDecl& entityDecl |
| , const bool isPEDecl |
| , const bool isIgnored |
| ) |
| { |
| EntityImpl* entity = ((DocumentImpl*)fDocument.fImpl)->createEntity(entityDecl.getName()); |
| |
| entity->setPublicId(entityDecl.getPublicId()); |
| entity->setSystemId(entityDecl.getSystemId()); |
| entity->setNotationName(entityDecl.getNotationName()); |
| |
| fDocumentType->entities->setNamedItem( entity ); |
| |
| if (fDocumentType->isIntSubsetReading()) |
| { |
| //add thes chars to internalSubset variable |
| DOMString entityName; |
| entityName.appendData(chOpenAngle); |
| entityName.appendData(chBang); |
| entityName.appendData(XMLUni::fgEntityString); |
| entityName.appendData(chSpace); |
| |
| entityName.appendData(entityDecl.getName()); |
| DOMString id = entity->getPublicId(); |
| if (id != 0) { |
| entityName.appendData(chSpace); |
| entityName.appendData(XMLUni::fgPubIDString); |
| entityName.appendData(chSpace); |
| entityName.appendData(chDoubleQuote); |
| entityName.appendData(id); |
| entityName.appendData(chDoubleQuote); |
| } |
| id = entity->getSystemId(); |
| if (id != 0) { |
| entityName.appendData(chSpace); |
| entityName.appendData(XMLUni::fgSysIDString); |
| entityName.appendData(chSpace); |
| entityName.appendData(chDoubleQuote); |
| entityName.appendData(id); |
| entityName.appendData(chDoubleQuote); |
| |
| } |
| id = entity->getNotationName(); |
| if (id != 0) { |
| entityName.appendData(chSpace); |
| entityName.appendData(XMLUni::fgNDATAString); |
| entityName.appendData(chSpace); |
| entityName.appendData(chDoubleQuote); |
| entityName.appendData(id); |
| entityName.appendData(chDoubleQuote); |
| } |
| entityName.appendData(chCloseAngle); |
| fDocumentType->internalSubset.appendData(entityName); |
| } |
| |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->entityDecl(entityDecl, isPEDecl, isIgnored); |
| } |
| } |
| |
| void DOMParser::resetDocType() |
| { |
| fDocumentType = null; |
| } |
| |
| void DOMParser::notationDecl |
| ( |
| const XMLNotationDecl& notDecl |
| , const bool isIgnored |
| ) |
| { |
| NotationImpl* notation = ((DocumentImpl*)fDocument.fImpl)->createNotation(notDecl.getName()); |
| notation->setPublicId(notDecl.getPublicId()); |
| notation->setPublicId(notDecl.getPublicId()); |
| |
| fDocumentType->notations->setNamedItem( notation ); |
| |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->notationDecl(notDecl, isIgnored); |
| } |
| } |
| |
| void DOMParser::startAttList |
| ( |
| const DTDElementDecl& elemDecl |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->startAttList(elemDecl); |
| } |
| } |
| |
| void DOMParser::startIntSubset() |
| { |
| fDocumentType->intSubsetReading = true; |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->startIntSubset(); |
| } |
| } |
| |
| void DOMParser::startExtSubset() |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->startExtSubset(); |
| } |
| } |
| |
| void DOMParser::TextDecl |
| ( |
| const XMLCh* const versionStr |
| , const XMLCh* const encodingStr |
| ) |
| { |
| if (fOldDocTypeHandler) |
| { |
| fOldDocTypeHandler->TextDecl(versionStr, encodingStr); |
| } |
| } |
| |
| |
| // to populate the entities in the documentType |
| void DOMParser::populateDocumentType() |
| { |
| if (fDocumentType == null) |
| return; |
| |
| |
| NameIdPoolEnumerator<DTDEntityDecl> entityPoolEnum = ((DTDValidator*)fValidator)->getEntityEnumerator(); |
| |
| |
| while(entityPoolEnum.hasMoreElements()) { |
| |
| DTDEntityDecl* entityDecl = &entityPoolEnum.nextElement(); |
| |
| EntityImpl* entity = ((DocumentImpl*)fDocument.fImpl)->createEntity(entityDecl->getName()); |
| entity->setPublicId(entityDecl->getPublicId()); |
| entity->setSystemId(entityDecl->getSystemId()); |
| entity->setNotationName(entityDecl->getNotationName()); |
| |
| fDocumentType->entities->setNamedItem( entity ); |
| } |
| |
| NameIdPoolEnumerator<XMLNotationDecl> notationPoolEnum = ((DTDValidator*)fValidator)->getNotationEnumerator(); |
| |
| while(notationPoolEnum.hasMoreElements()) { |
| XMLNotationDecl* notationDecl = ¬ationPoolEnum.nextElement(); |
| |
| NotationImpl* notation = ((DocumentImpl*)fDocument.fImpl)->createNotation(notationDecl->getName()); |
| notation->setPublicId(notationDecl->getPublicId()); |
| notation->setPublicId(notationDecl->getPublicId()); |
| |
| fDocumentType->notations->setNamedItem( notation ); |
| } |
| |
| } |