/* * The Apache Software License, Version 1.1 * * Copyright (c) 2001 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) 2001, International * Business Machines, Inc., http://www.ibm.com . For more information * on the Apache Software Foundation, please see * . */ /** * This file contains code to build the DOM tree. It registers a document * handler with the scanner. In these handler methods, appropriate IDOM nodes * are created and added to the DOM tree. * * $Id: IDOMParser.cpp,v 1.1.1.1 2002/02/01 22:22:05 peiyongz Exp $ * */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // --------------------------------------------------------------------------- // IDOMParser: Constructors and Destructor // --------------------------------------------------------------------------- IDOMParser::IDOMParser(XMLValidator* const valToAdopt) : fErrorHandler(0) , fEntityResolver(0) , fCreateEntityReferenceNodes(false) , fIncludeIgnorableWhitespace(true) , fNodeStack(0) , fScanner(0) , fDocument(0) , fDocumentVector(0) { // // Create a scanner and tell it what validator to use. Then set us // as the document event handler so we can fill the IDOM document. // fScanner = new XMLScanner(valToAdopt); fScanner->setDocHandler(this); fScanner->setDocTypeHandler(this); fNodeStack = new ValueStackOf(64); this->reset(); } IDOMParser::~IDOMParser() { if (fDocumentVector) delete fDocumentVector; delete fDocument; delete fNodeStack; delete fScanner; } void IDOMParser::reset() { // if fDocument exists already, store the old pointer in the vector for deletion later if (fDocument) { if (!fDocumentVector) { // allocate the vector if not exists yet fDocumentVector = new RefVectorOf(10, true) ; } fDocumentVector->addElement(fDocument); } fDocument = 0; resetDocType(); fCurrentParent = 0; fCurrentNode = 0; fParseInProgress = false; fWithinElement = false; fNodeStack->removeAllElements(); }; // --------------------------------------------------------------------------- // IDOMParser: Getter methods // --------------------------------------------------------------------------- IDOM_Document* IDOMParser::getDocument() { return fDocument; } const XMLValidator& IDOMParser::getValidator() const { return *fScanner->getValidator(); } bool IDOMParser::getDoNamespaces() const { return fScanner->getDoNamespaces(); } bool IDOMParser::getExitOnFirstFatalError() const { return fScanner->getExitOnFirstFatal(); } bool IDOMParser::getValidationConstraintFatal() const { return fScanner->getValidationConstraintFatal(); } IDOMParser::ValSchemes IDOMParser::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; } bool IDOMParser::getDoSchema() const { return fScanner->getDoSchema(); } bool IDOMParser::getValidationSchemaFullChecking() const { return fScanner->getValidationSchemaFullChecking(); } int IDOMParser::getErrorCount() const { return fScanner->getErrorCount(); } XMLCh* IDOMParser::getExternalSchemaLocation() const { return fScanner->getExternalSchemaLocation(); } XMLCh* IDOMParser::getExternalNoNamespaceSchemaLocation() const { return fScanner->getExternalNoNamespaceSchemaLocation(); } // --------------------------------------------------------------------------- // IDOMParser: Setter methods // --------------------------------------------------------------------------- void IDOMParser::setDoNamespaces(const bool newState) { fScanner->setDoNamespaces(newState); } void IDOMParser::setErrorHandler(ErrorHandler* const handler) { fErrorHandler = handler; if (fErrorHandler) { fScanner->setErrorReporter(this); fScanner->setErrorHandler(fErrorHandler); } else { fScanner->setErrorReporter(0); fScanner->setErrorHandler(0); } } void IDOMParser::setEntityResolver(EntityResolver* const handler) { fEntityResolver = handler; if (fEntityResolver) { fScanner->setEntityHandler(this); fScanner->setEntityResolver(fEntityResolver); } else { fScanner->setEntityHandler(0); fScanner->setEntityResolver(0); } } void IDOMParser::setExitOnFirstFatalError(const bool newState) { fScanner->setExitOnFirstFatal(newState); } void IDOMParser::setValidationConstraintFatal(const bool newState) { fScanner->setValidationConstraintFatal(newState); } void IDOMParser::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); } void IDOMParser::setDoSchema(const bool newState) { fScanner->setDoSchema(newState); } void IDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking) { fScanner->setValidationSchemaFullChecking(schemaFullChecking); } void IDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation) { fScanner->setExternalSchemaLocation(schemaLocation); } void IDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation) { fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation); } void IDOMParser::setExternalSchemaLocation(const char* const schemaLocation) { fScanner->setExternalSchemaLocation(schemaLocation); } void IDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation) { fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation); } // --------------------------------------------------------------------------- // IDOMParser: Parsing methods // --------------------------------------------------------------------------- void IDOMParser::parse(const InputSource& source, const bool reuseGrammar) { // Avoid multiple entrance if (fParseInProgress) ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); try { fParseInProgress = true; fScanner->scanDocument(source, reuseGrammar); fParseInProgress = false; } catch(...) { fParseInProgress = false; throw; } } void IDOMParser::parse(const XMLCh* const systemId, const bool reuseGrammar) { // Avoid multiple entrance if (fParseInProgress) ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); try { fParseInProgress = true; fScanner->scanDocument(systemId, reuseGrammar); fParseInProgress = false; } catch(...) { fParseInProgress = false; throw; } } void IDOMParser::parse(const char* const systemId, const bool reuseGrammar) { // Avoid multiple entrance if (fParseInProgress) ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); try { fParseInProgress = true; fScanner->scanDocument(systemId, reuseGrammar); fParseInProgress = false; } catch(...) { fParseInProgress = false; throw; } } // --------------------------------------------------------------------------- // IDOMParser: Progressive parse methods // --------------------------------------------------------------------------- bool IDOMParser::parseFirst( const XMLCh* const systemId , XMLPScanToken& toFill , const bool reuseGrammar) { // // 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, reuseGrammar); } bool IDOMParser::parseFirst( const char* const systemId , XMLPScanToken& toFill , const bool reuseGrammar) { // // 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, reuseGrammar); } bool IDOMParser::parseFirst( const InputSource& source , XMLPScanToken& toFill , const bool reuseGrammar) { // // 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, reuseGrammar); } bool IDOMParser::parseNext(XMLPScanToken& token) { return fScanner->scanNext(token); } void IDOMParser::parseReset(XMLPScanToken& token) { // Reset the scanner, and then reset the parser fScanner->scanReset(token); reset(); } // --------------------------------------------------------------------------- // IDOMParser: Utilities // --------------------------------------------------------------------------- void IDOMParser::resetDocumentPool() { // We cannot enter here while a regular parse is in progress. if (fParseInProgress) ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress); if (fDocumentVector) fDocumentVector->removeAllElements(); delete fDocument; fDocument = 0; } // --------------------------------------------------------------------------- // IDOMParser: Implementation of the XMLErrorReporter interface // --------------------------------------------------------------------------- void IDOMParser::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 IDOMParser::resetErrors() { } // --------------------------------------------------------------------------- // IDOMParser: Implementation of XMLEntityHandler interface // --------------------------------------------------------------------------- InputSource* IDOMParser::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; } // --------------------------------------------------------------------------- // IDOMParser: Implementation of XMLDocumentHandler interface // --------------------------------------------------------------------------- void IDOMParser::docCharacters( const XMLCh* const chars , const unsigned int length , const bool cdataSection) { // Ignore chars outside of content if (!fWithinElement) return; // idom_revisit. Is it really safe to null-terminate here? // Does the scanner do it already? // If scanner goes up to the very end of an unterminated // buffer, we may be stepping on something bad here. // Probably best to modify the scanner to null terminate. XMLCh savedChar = chars[length]; XMLCh *ncChars = (XMLCh *)chars; // cast off const ncChars[length] = 0; if (cdataSection == true) { IDOM_CDATASection *node = fDocument->createCDATASection(chars); fCurrentParent->appendChild(node); fCurrentNode = node; } else { if (fCurrentNode->getNodeType() == IDOM_Node::TEXT_NODE) { IDOM_Text *node = (IDOM_Text *)fCurrentNode; node->appendData(chars); } else { IDOM_Text *node = fDocument->createTextNode(chars); //If the node type is entityRef then set the readOnly flag to false before appending node if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) { IDEntityReferenceImpl *erImpl = (IDEntityReferenceImpl *) fCurrentParent; bool oldReadFlag = erImpl->fNode.isReadOnly(); erImpl->fNode.isReadOnly(false); fCurrentParent->appendChild(node); erImpl->fNode.isReadOnly(oldReadFlag); } else { fCurrentParent->appendChild(node); } fCurrentNode = node; } } ncChars[length] = savedChar; return; } void IDOMParser::docComment(const XMLCh* const comment) { IDOM_Comment *dcom = fDocument->createComment(comment); fCurrentParent->appendChild(dcom); fCurrentNode = dcom; } void IDOMParser::docPI( const XMLCh* const target , const XMLCh* const data) { IDOM_ProcessingInstruction *pi = fDocument->createProcessingInstruction ( target , data ); fCurrentParent->appendChild(pi); fCurrentNode = pi; } void IDOMParser::endEntityReference(const XMLEntityDecl& entDecl) { if (fCreateEntityReferenceNodes == true) { fCurrentParent = fNodeStack->pop(); fCurrentNode = fCurrentParent; } } void IDOMParser::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 IDOMParser::ignorableWhitespace(const XMLCh* const chars , const unsigned int length , const bool cdataSection) { // Ignore chars before the root element if (!fWithinElement || !fIncludeIgnorableWhitespace) return; // idom_revisit. Not safe to slam in a null like this. XMLCh savedChar = chars[length]; XMLCh *ncChars = (XMLCh *)chars; // cast off const ncChars[length] = chNull; if (fCurrentNode->getNodeType() == IDOM_Node::TEXT_NODE) { IDOM_Text *node = (IDOM_Text *)fCurrentNode; node->appendData(chars); } else { IDTextImpl *node = (IDTextImpl *)fDocument->createTextNode(chars); node->setIgnorableWhitespace(true); //If the node type is entityRef then set the readOnly flag to false before appending node if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) { IDEntityReferenceImpl *erImpl = (IDEntityReferenceImpl *) fCurrentParent; bool oldReadFlag = erImpl->fNode.isReadOnly(); erImpl->fNode.isReadOnly(false); fCurrentParent->appendChild(node); erImpl->fNode.isReadOnly(oldReadFlag); } else { fCurrentParent->appendChild(node); } fCurrentNode = node; } ncChars[length] = savedChar; } void IDOMParser::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 IDOM document itself. // this->reset(); fDocument = (IDDocumentImpl *)IDOM_DOMImplementation::getImplementation()->createDocument(); } void IDOMParser::startDocument() { // Just set the document as the current parent and current node fCurrentParent = fDocument; fCurrentNode = fDocument; // set IDOM error checking off fDocument->setErrorChecking(false); } void IDOMParser::endDocument() { // set IDOM error checking back on fDocument->setErrorChecking(true); } void IDOMParser::startElement(const XMLElementDecl& elemDecl , const unsigned int urlId , const XMLCh* const elemPrefix , const RefVectorOf& attrList , const unsigned int attrCount , const bool isEmpty , const bool isRoot) { IDOM_Element *elem; if (fScanner -> getDoNamespaces()) { //IDOM Level 2, doNamespaces on XMLBuffer buf; XMLCh* namespaceURI = 0; if (urlId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix fScanner->getURIText(urlId, buf); //get namespaceURI namespaceURI = buf.getRawBuffer(); } elem = fDocument->createElementNS(namespaceURI, elemDecl.getFullName()); IDElementImpl *elemImpl = (IDElementImpl *) elem; 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 = fScanner->getXMLNSNamespaceId(); if (attrURIId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix fScanner->getURIText(attrURIId, buf); //get namespaceURI namespaceURI = buf.getRawBuffer(); } // idom_revisit. Optimize to init the named node map to the // right size up front. IDAttrImpl *attr = (IDAttrImpl *) fDocument->createAttributeNS(namespaceURI, oneAttrib->getQName()); attr->setValue(oneAttrib -> getValue()); elemImpl->setAttributeNode(attr); //IDAttrImpl *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 (fDocument->fNodeIDMap == 0) fDocument->fNodeIDMap = new (fDocument) IDNodeIDMap(500, fDocument); fDocument->fNodeIDMap->add(attr); attr->fNode.isIdAttr(true); } attr->setSpecified(oneAttrib->getSpecified()); } } else { //DOM Level 1 elem = fDocument->createElement(elemDecl.getFullName()); IDElementImpl *elemImpl = (IDElementImpl *) elem; for (unsigned int index = 0; index < attrCount; ++index) { const XMLAttr* oneAttrib = attrList.elementAt(index); //AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue()); IDAttrImpl *attr = (IDAttrImpl *) fDocument->createAttribute(oneAttrib->getName()); attr->setValue(oneAttrib -> getValue()); elemImpl->setAttributeNode(attr); 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 (fDocument->fNodeIDMap == 0) fDocument->fNodeIDMap = new (fDocument) IDNodeIDMap(500, fDocument); fDocument->fNodeIDMap->add(attr); attr->fNode.isIdAttr(true); } } } //If the node type is entityRef then set the readOnly flag to false before appending node bool oldReadFlag; if (fCurrentParent->getNodeType() == IDOM_Node::ENTITY_REFERENCE_NODE) { IDEntityReferenceImpl *erNode = (IDEntityReferenceImpl *)fCurrentParent; oldReadFlag = erNode->fNode.isReadOnly(); erNode->fNode.isReadOnly(false); fCurrentParent->appendChild(elem); erNode->fNode.isReadOnly(oldReadFlag); } else { fCurrentParent->appendChild(elem); } 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 IDOMParser::startEntityReference(const XMLEntityDecl& entDecl) { if (fCreateEntityReferenceNodes == true) { const XMLCh * entName = entDecl.getName(); IDOM_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. // We'd decide later whether the entity nodes should be created by a // separated method in parser or not. For now just stick it in if // the ref nodes are created IDOM_NamedNodeMap *entities = fDocumentType->getEntities(); IDEntityImpl* entity = (IDEntityImpl*)entities->getNamedItem(entName); entity->setEntityRef(er); } } void IDOMParser::XMLDecl(const XMLCh* const version , const XMLCh* const encoding , const XMLCh* const standalone , const XMLCh* const actualEncStr) { // placehold for DOM Level 3 } // --------------------------------------------------------------------------- // IDOMParser: Deprecated methods // --------------------------------------------------------------------------- bool IDOMParser::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 IDOMParser::setDoValidation(const bool newState) { fScanner->setDoValidation ( newState ? XMLScanner::Val_Always : XMLScanner::Val_Never ); } //doctypehandler interfaces void IDOMParser::attDef ( const DTDElementDecl& elemDecl , const DTDAttDef& attDef , const bool ignoring ) { if (fDocumentType->isIntSubsetReading()) { XMLBuffer attString; if (elemDecl.hasAttDefs()) { attString.append(chOpenAngle); attString.append(chBang); attString.append(XMLUni::fgAttListString); attString.append(chSpace); attString.append(elemDecl.getFullName()); attString.append(chSpace); attString.append(attDef.getFullName()); // Get the type and display it const XMLAttDef::AttTypes type = attDef.getType(); switch(type) { case XMLAttDef::CData : attString.append(chSpace); attString.append(XMLUni::fgCDATAString); break; case XMLAttDef::ID : attString.append(chSpace); attString.append(XMLUni::fgIDString); break; case XMLAttDef::IDRef : attString.append(chSpace); attString.append(XMLUni::fgIDRefString); break; case XMLAttDef::IDRefs : attString.append(chSpace); attString.append(XMLUni::fgIDRefsString); break; case XMLAttDef::Entity : attString.append(chSpace); attString.append(XMLUni::fgEntityString); break; case XMLAttDef::Entities : attString.append(chSpace); attString.append(XMLUni::fgEntitiesString); break; case XMLAttDef::NmToken : attString.append(chSpace); attString.append(XMLUni::fgNmTokenString); break; case XMLAttDef::NmTokens : attString.append(chSpace); attString.append(XMLUni::fgNmTokensString); break; case XMLAttDef::Notation : attString.append(chSpace); attString.append(XMLUni::fgNotationString); break; case XMLAttDef::Enumeration : attString.append(chSpace); const XMLCh* enumString = attDef.getEnumeration(); int length = XMLString::stringLen(enumString); if (length > 0) { XMLBuffer anotherEnumString; anotherEnumString.append(chOpenParen ); for(int i=0; isetInternalSubset(attString.getRawBuffer()); } } } void IDOMParser::doctypeComment ( const XMLCh* const comment ) { if (fDocumentType->isIntSubsetReading()) { if (comment != 0) { XMLBuffer comString; comString.append(XMLUni::fgCommentString); comString.append(chSpace); comString.append(comment); comString.append(chSpace); comString.append(chDash); comString.append(chDash); comString.append(chCloseAngle); fDocumentType->setInternalSubset(comString.getRawBuffer()); } } } void IDOMParser::doctypeDecl ( const DTDElementDecl& elemDecl , const XMLCh* const publicId , const XMLCh* const systemId , const bool hasIntSubset ) { fDocumentType = (IDDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId); fDocument->setDocumentType(fDocumentType); } void IDOMParser::doctypePI ( const XMLCh* const target , const XMLCh* const data ) { if (fDocumentType->isIntSubsetReading()) { //add these chars to internalSubset variable XMLBuffer pi; pi.append(chOpenAngle); pi.append(chQuestion); pi.append(target); pi.append(chSpace); pi.append(data); pi.append(chQuestion); pi.append(chCloseAngle); fDocumentType->setInternalSubset(pi.getRawBuffer()); } } void IDOMParser::doctypeWhitespace ( const XMLCh* const chars , const unsigned int length ) { if (fDocumentType->isIntSubsetReading()) fDocumentType->setInternalSubset(chars); } void IDOMParser::elementDecl ( const DTDElementDecl& decl , const bool isIgnored ) { if (fDocumentType->isIntSubsetReading()) { XMLBuffer elemDecl; elemDecl.append(chOpenAngle); elemDecl.append(chBang); elemDecl.append(XMLUni::fgElemString); elemDecl.append(chSpace); elemDecl.append(decl.getFullName()); //get the ContentSpec information const XMLCh* contentModel = decl.getFormattedContentModel(); if (contentModel != 0) { elemDecl.append(chSpace); elemDecl.append(contentModel); } elemDecl.append(chCloseAngle); fDocumentType->setInternalSubset(elemDecl.getRawBuffer()); } } void IDOMParser::endAttList ( const DTDElementDecl& elemDecl ) { // this section sets up default attributes. // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements // default attribute data attached to the document is used to conform to the // IDOM spec regarding creating element nodes & removing attributes with default values // see DocumentTypeImpl if (elemDecl.hasAttDefs()) { XMLAttDefList* defAttrs = &elemDecl.getAttDefList(); XMLAttDef* attr = 0; IDAttrImpl * insertAttr = 0; IDOM_Element *elem = fDocument->createElement(elemDecl.getFullName()); IDElementImpl *elemImpl = (IDElementImpl *) elem; while (defAttrs->hasMoreElements()) { attr = &defAttrs->nextElement(); if (attr->getValue() != 0) { if (fScanner->getDoNamespaces()) { // DOM Level 2 wants all namespace declaration attributes // to be bound to "http://www.w3.org/2000/xmlns/" // So as long as the XML parser doesn't do it, it needs to // done here. const XMLCh* qualifiedName = attr->getFullName(); int index = IDDocumentImpl::indexofQualifiedName(qualifiedName); XMLBuffer buf; static const XMLCh XMLNS[] = { chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull}; if (index > 0) { // there is prefix // map to XML URI for all cases except when prefix == "xmlns" XMLCh* prefix; XMLCh temp[1000]; if (index > 999) prefix = new XMLCh[index+1]; else prefix = temp; XMLString::subString(prefix ,qualifiedName, 0, index); if (!XMLString::compareString(prefix,XMLNS)) buf.append(XMLUni::fgXMLNSURIName); else buf.append(XMLUni::fgXMLURIName); if (index > 999) delete prefix; } else { // No prefix if (!XMLString::compareString(qualifiedName,XMLNS)) buf.append(XMLUni::fgXMLNSURIName); } insertAttr = (IDAttrImpl *) fDocument->createAttributeNS( buf.getRawBuffer(), // NameSpaceURI qualifiedName); // qualified name } else { // Namespaces is turned off... insertAttr = (IDAttrImpl *) fDocument->createAttribute(attr->getFullName()); } insertAttr->setValue(attr->getValue()); elemImpl->setAttributeNode(insertAttr); insertAttr->setSpecified(false); } } fDocumentType->getElements()->setNamedItem(elemImpl); } } void IDOMParser::endIntSubset() { fDocumentType->intSubsetReading = false; } void IDOMParser::endExtSubset() { } void IDOMParser::entityDecl ( const DTDEntityDecl& entityDecl , const bool isPEDecl , const bool isIgnored ) { IDEntityImpl* entity = (IDEntityImpl *) fDocument->createEntity(entityDecl.getName()); entity->setPublicId(entityDecl.getPublicId()); entity->setSystemId(entityDecl.getSystemId()); entity->setNotationName(entityDecl.getNotationName()); IDEntityImpl *previousDef = (IDEntityImpl *) fDocumentType->getEntities()->setNamedItem( entity ); #ifdef idom_revisit // // If this new entity node is replacing an entity node that was already // in the entities named node map (happens if documents redefine the // predefined entited such as lt), we need to delete the original // entitiy node, assuming no-one else was referencing it. // if (previousDef != 0 && previousDef->nodeRefCount == 0) NodeImpl::deleteIf(previousDef); #endif if (fDocumentType->isIntSubsetReading()) { //add thes chars to internalSubset variable XMLBuffer entityName; entityName.append(chOpenAngle); entityName.append(chBang); entityName.append(XMLUni::fgEntityString); entityName.append(chSpace); entityName.append(entityDecl.getName()); const XMLCh* id = entity->getPublicId(); if (id != 0) { entityName.append(chSpace); entityName.append(XMLUni::fgPubIDString); entityName.append(chSpace); entityName.append(chDoubleQuote); entityName.append(id); entityName.append(chDoubleQuote); } id = entity->getSystemId(); if (id != 0) { entityName.append(chSpace); entityName.append(XMLUni::fgSysIDString); entityName.append(chSpace); entityName.append(chDoubleQuote); entityName.append(id); entityName.append(chDoubleQuote); } id = entity->getNotationName(); if (id != 0) { entityName.append(chSpace); entityName.append(XMLUni::fgNDATAString); entityName.append(chSpace); entityName.append(chDoubleQuote); entityName.append(id); entityName.append(chDoubleQuote); } id = entityDecl.getValue(); if (id !=0) { entityName.append(chSpace); entityName.append(chDoubleQuote); entityName.append(id); entityName.append(chDoubleQuote); } entityName.append(chCloseAngle); fDocumentType->setInternalSubset(entityName.getRawBuffer()); } } void IDOMParser::resetDocType() { fDocumentType = 0; } void IDOMParser::notationDecl ( const XMLNotationDecl& notDecl , const bool isIgnored ) { IDNotationImpl* notation = (IDNotationImpl *)fDocument->createNotation(notDecl.getName()); notation->setPublicId(notDecl.getPublicId()); notation->setSystemId(notDecl.getSystemId()); fDocumentType->getNotations()->setNamedItem( notation ); } void IDOMParser::startAttList ( const DTDElementDecl& elemDecl ) { } void IDOMParser::startIntSubset() { fDocumentType->intSubsetReading = true; } void IDOMParser::startExtSubset() { } void IDOMParser::TextDecl ( const XMLCh* const versionStr , const XMLCh* const encodingStr ) { }