blob: 131f821c131a43f7f2bddf3b02906d044391f048 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/**
* 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: AbstractDOMParser.cpp 568078 2007-08-21 11:43:25Z amassari $
*
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/parsers/AbstractDOMParser.hpp>
#include <xercesc/internal/XMLScannerResolver.hpp>
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/XMLNotationDecl.hpp>
#include <xercesc/framework/XMLValidator.hpp>
#include <xercesc/framework/psvi/PSVIElement.hpp>
#include <xercesc/framework/psvi/PSVIAttribute.hpp>
#include <xercesc/framework/psvi/PSVIAttributeList.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/util/IOException.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/impl/DOMAttrImpl.hpp>
#include <xercesc/dom/impl/DOMTypeInfoImpl.hpp>
#include <xercesc/dom/DOMCDATASection.hpp>
#include <xercesc/dom/DOMComment.hpp>
#include <xercesc/dom/impl/DOMTextImpl.hpp>
#include <xercesc/dom/impl/DOMDocumentImpl.hpp>
#include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/impl/DOMElementNSImpl.hpp>
#include <xercesc/dom/impl/DOMEntityImpl.hpp>
#include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp>
#include <xercesc/dom/impl/DOMNotationImpl.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
#include <xercesc/dom/impl/DOMNodeIDMap.hpp>
#include <xercesc/dom/impl/DOMCasts.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/common/GrammarResolver.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
XERCES_CPP_NAMESPACE_BEGIN
// ---------------------------------------------------------------------------
// AbstractDOMParser: Constructors and Destructor
// ---------------------------------------------------------------------------
typedef JanitorMemFunCall<AbstractDOMParser> CleanupType;
typedef JanitorMemFunCall<AbstractDOMParser> ResetInProgressType;
AbstractDOMParser::AbstractDOMParser( XMLValidator* const valToAdopt
, MemoryManager* const manager
, XMLGrammarPool* const gramPool) :
fCreateEntityReferenceNodes(true)
, fIncludeIgnorableWhitespace(true)
, fWithinElement(false)
, fParseInProgress(false)
, fCreateCommentNodes(true)
, fDocumentAdoptedByUser(false)
, fCreateSchemaInfo(false)
, fScanner(0)
, fImplementationFeatures(0)
, fCurrentParent(0)
, fCurrentNode(0)
, fCurrentEntity(0)
, fDocument(0)
, fNodeStack(0)
, fDocumentType(0)
, fDocumentVector(0)
, fGrammarResolver(0)
, fURIStringPool(0)
, fValidator(valToAdopt)
, fMemoryManager(manager)
, fGrammarPool(gramPool)
, fBufMgr(manager)
, fInternalSubset(fBufMgr.bidOnBuffer())
, fPSVIHandler(0)
{
CleanupType cleanup(this, &AbstractDOMParser::cleanUp);
try
{
initialize();
}
catch(const OutOfMemoryException&)
{
// Don't cleanup when out of memory, since executing the
// code can cause problems.
cleanup.release();
throw;
}
cleanup.release();
}
AbstractDOMParser::~AbstractDOMParser()
{
cleanUp();
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Initialize/CleanUp methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::initialize()
{
// Create grammar resolver and string pool to pass to the scanner
fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager);
fURIStringPool = fGrammarResolver->getStringPool();
// 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 = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager);
fScanner->setDocHandler(this);
fScanner->setDocTypeHandler(this);
fScanner->setURIStringPool(fURIStringPool);
fNodeStack = new (fMemoryManager) ValueStackOf<DOMNode*>(64, fMemoryManager);
this->reset();
}
void AbstractDOMParser::cleanUp()
{
if (fDocumentVector)
delete fDocumentVector;
if (!fDocumentAdoptedByUser && fDocument)
fDocument->release();
delete fNodeStack;
delete fScanner;
delete fGrammarResolver;
// grammar pool *always* owns this
//delete fURIStringPool;
fMemoryManager->deallocate(fImplementationFeatures);
if (fValidator)
delete fValidator;
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Utilities
// ---------------------------------------------------------------------------
void AbstractDOMParser::reset()
{
// if fDocument exists already, store the old pointer in the vector for deletion later
if (fDocument && !fDocumentAdoptedByUser) {
if (!fDocumentVector) {
// allocate the vector if not exists yet
fDocumentVector = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ;
}
fDocumentVector->addElement(fDocument);
}
fDocument = 0;
resetDocType();
fCurrentParent = 0;
fCurrentNode = 0;
fCurrentEntity = 0;
fParseInProgress = false;
fWithinElement = false;
fDocumentAdoptedByUser = false;
fNodeStack->removeAllElements();
fInternalSubset.reset();
}
void AbstractDOMParser::resetInProgress()
{
fParseInProgress = false;
}
void AbstractDOMParser::resetPool()
{
// We cannot enter here while a regular parse is in progress.
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
if (fDocumentVector)
fDocumentVector->removeAllElements();
if (!fDocumentAdoptedByUser && fDocument)
fDocument->release();
fDocument = 0;
}
bool AbstractDOMParser::isDocumentAdopted() const
{
return fDocumentAdoptedByUser;
}
DOMDocument* AbstractDOMParser::adoptDocument()
{
fDocumentAdoptedByUser = true;
return fDocument;
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Getter methods
// ---------------------------------------------------------------------------
DOMDocument* AbstractDOMParser::getDocument()
{
return fDocument;
}
const XMLValidator& AbstractDOMParser::getValidator() const
{
return *fScanner->getValidator();
}
bool AbstractDOMParser::getDoNamespaces() const
{
return fScanner->getDoNamespaces();
}
bool AbstractDOMParser::getGenerateSyntheticAnnotations() const
{
return fScanner->getGenerateSyntheticAnnotations();
}
bool AbstractDOMParser::getValidateAnnotations() const
{
return fScanner->getValidateAnnotations();
}
bool AbstractDOMParser::getExitOnFirstFatalError() const
{
return fScanner->getExitOnFirstFatal();
}
bool AbstractDOMParser::getValidationConstraintFatal() const
{
return fScanner->getValidationConstraintFatal();
}
AbstractDOMParser::ValSchemes AbstractDOMParser::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 AbstractDOMParser::getDoSchema() const
{
return fScanner->getDoSchema();
}
bool AbstractDOMParser::getValidationSchemaFullChecking() const
{
return fScanner->getValidationSchemaFullChecking();
}
bool AbstractDOMParser::getIdentityConstraintChecking() const
{
return fScanner->getIdentityConstraintChecking();
}
int AbstractDOMParser::getErrorCount() const
{
return fScanner->getErrorCount();
}
XMLCh* AbstractDOMParser::getExternalSchemaLocation() const
{
return fScanner->getExternalSchemaLocation();
}
XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const
{
return fScanner->getExternalNoNamespaceSchemaLocation();
}
SecurityManager* AbstractDOMParser::getSecurityManager() const
{
return fScanner->getSecurityManager();
}
bool AbstractDOMParser::getLoadExternalDTD() const
{
return fScanner->getLoadExternalDTD();
}
bool AbstractDOMParser::getCalculateSrcOfs() const
{
return fScanner->getCalculateSrcOfs();
}
bool AbstractDOMParser::getStandardUriConformant() const
{
return fScanner->getStandardUriConformant();
}
bool AbstractDOMParser::getIgnoreAnnotations() const
{
return fScanner->getIgnoreAnnotations();
}
bool AbstractDOMParser::getDisableDefaultEntityResolution() const
{
return fScanner->getDisableDefaultEntityResolution();
}
bool AbstractDOMParser::getSkipDTDValidation() const
{
return fScanner->getSkipDTDValidation();
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Setter methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::setPSVIHandler(PSVIHandler* const handler)
{
fPSVIHandler = handler;
if (fPSVIHandler) {
fScanner->setPSVIHandler(this);
}
else if(!fCreateSchemaInfo) {
fScanner->setPSVIHandler(0);
}
}
void AbstractDOMParser::setDoNamespaces(const bool newState)
{
fScanner->setDoNamespaces(newState);
}
void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState)
{
fScanner->setGenerateSyntheticAnnotations(newState);
}
void AbstractDOMParser::setValidateAnnotations(const bool newState)
{
fScanner->setValidateAnnotations(newState);
}
void AbstractDOMParser::setExitOnFirstFatalError(const bool newState)
{
fScanner->setExitOnFirstFatal(newState);
}
void AbstractDOMParser::setValidationConstraintFatal(const bool newState)
{
fScanner->setValidationConstraintFatal(newState);
}
void AbstractDOMParser::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 AbstractDOMParser::setDoSchema(const bool newState)
{
fScanner->setDoSchema(newState);
}
void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
{
fScanner->setValidationSchemaFullChecking(schemaFullChecking);
}
void AbstractDOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking)
{
fScanner->setIdentityConstraintChecking(identityConstraintChecking);
}
void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
{
fScanner->setExternalSchemaLocation(schemaLocation);
}
void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
{
fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}
void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
{
fScanner->setExternalSchemaLocation(schemaLocation);
}
void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
{
fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}
void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager)
{
// since this could impact various components, don't permit it to change
// during a parse
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
fScanner->setSecurityManager(securityManager);
}
void AbstractDOMParser::setLoadExternalDTD(const bool newState)
{
fScanner->setLoadExternalDTD(newState);
}
void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
{
fScanner->setCalculateSrcOfs(newState);
}
void AbstractDOMParser::setStandardUriConformant(const bool newState)
{
fScanner->setStandardUriConformant(newState);
}
void AbstractDOMParser::useScanner(const XMLCh* const scannerName)
{
XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
(
scannerName
, fValidator
, fGrammarResolver
, fMemoryManager
);
if (tempScanner) {
tempScanner->setParseSettings(fScanner);
tempScanner->setURIStringPool(fURIStringPool);
delete fScanner;
fScanner = tempScanner;
}
}
void AbstractDOMParser::setCreateSchemaInfo(const bool create)
{
fCreateSchemaInfo = create;
if(fCreateSchemaInfo)
fScanner->setPSVIHandler(this);
else if(!fPSVIHandler)
fScanner->setPSVIHandler(0);
}
void AbstractDOMParser::setIgnoreAnnotations(const bool newValue)
{
fScanner->setIgnoreAnnotations(newValue);
}
void AbstractDOMParser::setDisableDefaultEntityResolution(const bool newValue)
{
fScanner->setDisableDefaultEntityResolution(newValue);
}
void AbstractDOMParser::setSkipDTDValidation(const bool newValue)
{
fScanner->setSkipDTDValidation(newValue);
}
void AbstractDOMParser::setDocument(DOMDocument* toSet)
{
fDocument = (DOMDocumentImpl *)toSet;
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Parsing methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::parse(const InputSource& source)
{
// Avoid multiple entrance
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress);
try
{
fParseInProgress = true;
fScanner->scanDocument(source);
}
catch(const OutOfMemoryException&)
{
resetInProgress.release();
throw;
}
}
void AbstractDOMParser::parse(const XMLCh* const systemId)
{
// Avoid multiple entrance
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress);
try
{
fParseInProgress = true;
fScanner->scanDocument(systemId);
}
catch(const OutOfMemoryException&)
{
resetInProgress.release();
throw;
}
}
void AbstractDOMParser::parse(const char* const systemId)
{
// Avoid multiple entrance
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
ResetInProgressType resetInProgress(this, &AbstractDOMParser::resetInProgress);
try
{
fParseInProgress = true;
fScanner->scanDocument(systemId);
}
catch(const OutOfMemoryException&)
{
resetInProgress.release();
throw;
}
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Progressive parse methods
// ---------------------------------------------------------------------------
bool AbstractDOMParser::parseFirst( const XMLCh* const systemId
, XMLPScanToken& toFill)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
// is in progress.
//
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
return fScanner->scanFirst(systemId, toFill);
}
bool AbstractDOMParser::parseFirst( const char* const systemId
, XMLPScanToken& toFill)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
// is in progress.
//
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
return fScanner->scanFirst(systemId, toFill);
}
bool AbstractDOMParser::parseFirst( const InputSource& source
, XMLPScanToken& toFill)
{
//
// Avoid multiple entrance. We cannot enter here while a regular parse
// is in progress.
//
if (fParseInProgress)
ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);
return fScanner->scanFirst(source, toFill);
}
bool AbstractDOMParser::parseNext(XMLPScanToken& token)
{
return fScanner->scanNext(token);
}
void AbstractDOMParser::parseReset(XMLPScanToken& token)
{
// Reset the scanner, and then reset the parser
fScanner->scanReset(token);
reset();
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Implementation of PSVIHandler interface
// ---------------------------------------------------------------------------
void AbstractDOMParser::handleElementPSVI(const XMLCh* const localName
, const XMLCh* const uri
, PSVIElement * elementInfo)
{
// associate the info now; if the user wants, she can override what we did
if(fCreateSchemaInfo)
{
DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, elementInfo->getValidity());
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validitation_Attempted, elementInfo->getValidationAttempted());
if(elementInfo->getTypeDefinition())
{
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, elementInfo->getTypeDefinition()->getTypeCategory());
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, elementInfo->getTypeDefinition()->getAnonymous());
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
fDocument->getPooledString(elementInfo->getTypeDefinition()->getNamespace()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
fDocument->getPooledString(elementInfo->getTypeDefinition()->getName()));
}
else if(elementInfo->getValidity()==PSVIItem::VALIDITY_VALID)
{
// if we are valid but we don't have a type validator, we are xs:anyType
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::COMPLEX_TYPE);
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgATTVAL_ANYTYPE);
}
if(elementInfo->getMemberTypeDefinition())
{
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, elementInfo->getMemberTypeDefinition()->getAnonymous());
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getNamespace()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getName()));
}
if(elementInfo->getElementDeclaration())
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Nil, elementInfo->getElementDeclaration()->getNillable());
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(elementInfo->getSchemaDefault()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(elementInfo->getSchemaNormalizedValue()));
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
((DOMElementNSImpl*)fCurrentParent)->setTypeInfo(typeInfo);
}
if(fPSVIHandler)
fPSVIHandler->handleElementPSVI(localName, uri, elementInfo);
}
void AbstractDOMParser::handlePartialElementPSVI(const XMLCh* const localName
, const XMLCh* const uri
, PSVIElement * elementInfo)
{
if(fPSVIHandler)
fPSVIHandler->handlePartialElementPSVI(localName, uri, elementInfo);
}
void AbstractDOMParser::handleAttributesPSVI( const XMLCh* const localName
, const XMLCh* const uri
, PSVIAttributeList * psviAttributes)
{
if(fCreateSchemaInfo)
{
for (unsigned int index=0; index < psviAttributes->getLength(); index++) {
XERCES_CPP_NAMESPACE_QUALIFIER PSVIAttribute *attrInfo=psviAttributes->getAttributePSVIAtIndex(index);
XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* pAttrNode=fCurrentNode->getAttributes()->getNamedItemNS(psviAttributes->getAttributeNamespaceAtIndex(index),
psviAttributes->getAttributeNameAtIndex(index));
if(pAttrNode!=NULL)
{
DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, attrInfo->getValidity());
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validitation_Attempted, attrInfo->getValidationAttempted());
if(attrInfo->getTypeDefinition())
{
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, attrInfo->getTypeDefinition()->getAnonymous());
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace,
fDocument->getPooledString(attrInfo->getTypeDefinition()->getNamespace()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name,
fDocument->getPooledString(attrInfo->getTypeDefinition()->getName()));
}
else if(attrInfo->getValidity()==PSVIItem::VALIDITY_VALID)
{
// if we are valid but we don't have a type validator, we are xs:anySimpleType
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgDT_ANYSIMPLETYPE);
}
if(attrInfo->getMemberTypeDefinition())
{
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, attrInfo->getMemberTypeDefinition()->getAnonymous());
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace,
fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getNamespace()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name,
fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getName()));
}
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(attrInfo->getSchemaDefault()));
typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(attrInfo->getSchemaNormalizedValue()));
typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
((DOMAttrImpl*)pAttrNode)->setTypeInfo(typeInfo);
}
}
}
// associate the info now; if the user wants, she can override what we did
if(fPSVIHandler)
fPSVIHandler->handleAttributesPSVI(localName, uri, psviAttributes);
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Implementation of XMLDocumentHandler interface
// ---------------------------------------------------------------------------
void AbstractDOMParser::docCharacters( const XMLCh* const chars
, const unsigned int length
, const bool cdataSection)
{
// Ignore chars outside of content
if (!fWithinElement)
return;
// 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)
{
DOMCDATASection *node = fDocument->createCDATASection(chars);
castToParentImpl (fCurrentParent)->appendChildFast (node);
fCurrentNode = node;
}
else
{
if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
{
DOMText *node = (DOMText *)fCurrentNode;
node->appendData(chars);
}
else
{
DOMText *node = fDocument->createTextNode(chars);
castToParentImpl (fCurrentParent)->appendChildFast (node);
fCurrentNode = node;
}
}
ncChars[length] = savedChar;
return;
}
void AbstractDOMParser::docComment(const XMLCh* const comment)
{
if (fCreateCommentNodes) {
DOMComment *dcom = fDocument->createComment(comment);
castToParentImpl (fCurrentParent)->appendChildFast (dcom);
fCurrentNode = dcom;
}
}
void AbstractDOMParser::docPI( const XMLCh* const target
, const XMLCh* const data)
{
DOMProcessingInstruction *pi = fDocument->createProcessingInstruction
(
target
, data
);
castToParentImpl (fCurrentParent)->appendChildFast (pi);
fCurrentNode = pi;
}
void AbstractDOMParser::endEntityReference(const XMLEntityDecl&)
{
if (!fCreateEntityReferenceNodes) return;
DOMEntityReferenceImpl *erImpl = 0;
if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
erImpl = (DOMEntityReferenceImpl *) fCurrentParent;
fCurrentParent = fNodeStack->pop();
fCurrentNode = fCurrentParent;
if (erImpl)
erImpl->setReadOnly(true, true);
}
void AbstractDOMParser::endElement( const XMLElementDecl&
, const unsigned int
, const bool
, const XMLCh* const)
{
fCurrentNode = fCurrentParent;
fCurrentParent = fNodeStack->pop();
// If we've hit the end of content, clear the flag
if (fNodeStack->empty())
fWithinElement = false;
}
void AbstractDOMParser::elementTypeInfo( const XMLCh * const /*typeName*/
, const XMLCh * const /*typeURI*/)
{
}
void AbstractDOMParser::ignorableWhitespace( const XMLCh* const chars
, const unsigned int length
, const bool)
{
// Ignore chars before the root element
if (!fWithinElement || !fIncludeIgnorableWhitespace)
return;
// 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() == DOMNode::TEXT_NODE)
{
DOMText *node = (DOMText *)fCurrentNode;
node->appendData(chars);
}
else
{
DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars);
node->setIgnorableWhitespace(true);
castToParentImpl (fCurrentParent)->appendChildFast (node);
fCurrentNode = node;
}
ncChars[length] = savedChar;
}
void AbstractDOMParser::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 AbstractDOMParser::startDocument()
{
if(fImplementationFeatures == 0)
fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument(fMemoryManager);
else
fDocument = (DOMDocumentImpl *)DOMImplementationRegistry::getDOMImplementation(fImplementationFeatures)->createDocument(fMemoryManager);
// Just set the document as the current parent and current node
fCurrentParent = fDocument;
fCurrentNode = fDocument;
// set DOM error checking off
fDocument->setErrorChecking(false);
fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
fDocument->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
}
void AbstractDOMParser::endDocument()
{
// set DOM error checking back on
fDocument->setErrorChecking(true);
// DOM L2 does not support editing DocumentType nodes
if (fDocumentType && fScanner -> getDoNamespaces())
fDocumentType->setReadOnly(true, true);
}
void AbstractDOMParser::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)
{
DOMElement *elem;
DOMElementImpl *elemImpl;
const XMLCh* namespaceURI = 0;
//get the list for use in the loop
XMLAttDefList* defAttrs = 0;
if(elemDecl.hasAttDefs()) {
defAttrs = &elemDecl.getAttDefList();
}
if (fScanner -> getDoNamespaces()) { //DOM Level 2, doNamespaces on
if (urlId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
namespaceURI = fScanner->getURIText(urlId); //get namespaceURI
if (elemPrefix && *elemPrefix) {
XMLBufBid elemQName(&fBufMgr);
elemQName.set(elemPrefix);
elemQName.append(chColon);
elemQName.append(elemDecl.getBaseName());
elem = createElementNSNode(namespaceURI, elemQName.getRawBuffer());
}
else {
elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
}
}
else {
elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
}
elemImpl = (DOMElementImpl *) elem;
}
else { //DOM Level 1
elem = fDocument->createElement(elemDecl.getFullName());
elemImpl = (DOMElementImpl *) elem;
}
for (unsigned int index = 0; index < attrCount; ++index) {
const XMLAttr* oneAttrib = attrList.elementAt(index);
DOMAttrImpl *attr = 0;
DOMNode* remAttr = 0;
// revisit. Optimize to init the named node map to the
// right size up front.
if (fScanner -> getDoNamespaces()) { //DOM Level 2, doNamespaces on
unsigned int attrURIId = oneAttrib -> getURIId();
namespaceURI = 0;
if (XMLString::equals(oneAttrib -> getName(), XMLUni::fgXMLNSString)) { //for xmlns=...
attrURIId = fScanner->getXMLNSNamespaceId();
}
if (attrURIId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
namespaceURI = fScanner->getURIText(attrURIId); //get namespaceURI
}
attr = (DOMAttrImpl *)fDocument->createAttributeNS(namespaceURI, oneAttrib->getQName());
remAttr = elemImpl->setAttributeNodeNS(attr);
}
else {
attr = (DOMAttrImpl *)fDocument->createAttribute(oneAttrib->getName());
remAttr = elemImpl->setAttributeNode(attr);
}
attr->setValue(oneAttrib -> getValue());
if (remAttr)
remAttr->release();
// 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) DOMNodeIDMap(500, fDocument);
fDocument->fNodeIDMap->add(attr);
attr->fNode.isIdAttr(true);
}
attr->setSpecified(oneAttrib->getSpecified());
// store DTD validation information
if(fCreateSchemaInfo)
{
switch(oneAttrib->getType())
{
case XMLAttDef::CData: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
case XMLAttDef::ID: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
case XMLAttDef::IDRef: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
case XMLAttDef::IDRefs: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
case XMLAttDef::Entity: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
case XMLAttDef::Entities: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
case XMLAttDef::NmToken: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
case XMLAttDef::NmTokens: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
case XMLAttDef::Notation: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
case XMLAttDef::Enumeration: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
default: attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
}
}
}
// set up the default attributes
if (defAttrs != 0)
{
XMLAttDef* attr = 0;
DOMAttrImpl * insertAttr = 0;
for(unsigned int i=0; i<defAttrs->getAttDefCount(); i++)
{
attr = &defAttrs->getAttDef(i);
const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
if ((defType == XMLAttDef::Default)
|| (defType == XMLAttDef::Fixed))
{
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();
XMLBufBid bbPrefixQName(&fBufMgr);
XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
int colonPos = -1;
unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);
const XMLCh* namespaceURI = 0;
if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString)) //for xmlns=...
uriId = fScanner->getXMLNSNamespaceId();
if (uriId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
namespaceURI = fScanner->getURIText(uriId);
}
insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI, // NameSpaceURI
qualifiedName); // qualified name
DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
if (remAttr)
remAttr->release();
}
else
{
// Namespaces is turned off...
insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
if (remAttr)
remAttr->release();
}
//need to do this before the get as otherwise we overwrite any value in the attr
if (attr->getValue() != 0)
{
insertAttr->setValue(attr->getValue());
insertAttr->setSpecified(false);
}
// store DTD validation information
if(fCreateSchemaInfo)
{
switch(attr->getType())
{
case XMLAttDef::CData: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
case XMLAttDef::ID: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
case XMLAttDef::IDRef: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
case XMLAttDef::IDRefs: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
case XMLAttDef::Entity: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
case XMLAttDef::Entities: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
case XMLAttDef::NmToken: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
case XMLAttDef::NmTokens: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
case XMLAttDef::Notation: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
case XMLAttDef::Enumeration: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
default: insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
}
}
}
insertAttr = 0;
attr->reset();
}
}
if (fCurrentParent != fDocument)
castToParentImpl (fCurrentParent)->appendChildFast (elem);
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, elemPrefix);
}
void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
{
const XMLCh * entName = entDecl.getName();
DOMNamedNodeMap *entities = fDocumentType->getEntities();
DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName);
if (entity)
entity->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
fCurrentEntity = entity;
// Following line has been moved up so that erImpl is only declared
// and used if create entity ref flag is true
if (fCreateEntityReferenceNodes == true) {
DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);
//set the readOnly flag to false before appending node, will be reset
// in endEntityReference
DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
erImpl->setReadOnly(false, true);
castToParentImpl (fCurrentParent)->appendChildFast (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
if (entity)
entity->setEntityRef(er);
}
}
void AbstractDOMParser::XMLDecl(const XMLCh* const version
, const XMLCh* const encoding
, const XMLCh* const standalone
, const XMLCh* const actualEncStr)
{
fDocument->setStandalone(XMLString::equals(XMLUni::fgYesString, standalone));
fDocument->setVersion(version);
fDocument->setEncoding(encoding);
fDocument->setActualEncoding(actualEncStr);
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Helper methods
// ---------------------------------------------------------------------------
DOMElement* AbstractDOMParser::createElementNSNode(const XMLCh *namespaceURI,
const XMLCh *qualifiedName)
{
return fDocument->createElementNS(namespaceURI, qualifiedName);
}
// ---------------------------------------------------------------------------
// AbstractDOMParser: Deprecated methods
// ---------------------------------------------------------------------------
bool AbstractDOMParser::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 AbstractDOMParser::setDoValidation(const bool newState)
{
fScanner->setDoValidation
(
newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
);
}
//doctypehandler interfaces
void AbstractDOMParser::attDef
(
const DTDElementDecl& elemDecl
, const DTDAttDef& attDef
, const bool
)
{
if (fDocumentType->isIntSubsetReading())
{
if (elemDecl.hasAttDefs())
{
fInternalSubset.append(attDef.getFullName());
// Get the type and display it
const XMLAttDef::AttTypes type = attDef.getType();
switch(type)
{
case XMLAttDef::CData :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgCDATAString);
break;
case XMLAttDef::ID :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgIDString);
break;
case XMLAttDef::IDRef :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgIDRefString);
break;
case XMLAttDef::IDRefs :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgIDRefsString);
break;
case XMLAttDef::Entity :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgEntityString);
break;
case XMLAttDef::Entities :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgEntitiesString);
break;
case XMLAttDef::NmToken :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgNmTokenString);
break;
case XMLAttDef::NmTokens :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgNmTokensString);
break;
case XMLAttDef::Notation :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgNotationString);
break;
case XMLAttDef::Enumeration :
{
fInternalSubset.append(chSpace);
const XMLCh* enumString = attDef.getEnumeration();
int length = XMLString::stringLen(enumString);
if (length > 0) {
fInternalSubset.append(chOpenParen );
for(int i=0; i<length; i++) {
if (enumString[i] == chSpace)
fInternalSubset.append(chPipe);
else
fInternalSubset.append(enumString[i]);
}
fInternalSubset.append(chCloseParen);
}
}
break;
default:
// remaining types don't belong to a DTD
break;
}
//get te default types of the attlist
const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
switch(def)
{
case XMLAttDef::Required :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgRequiredString);
break;
case XMLAttDef::Implied :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgImpliedString);
break;
case XMLAttDef::Fixed :
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgFixedString);
break;
default:
// remaining types don't belong to a DTD
break;
}
const XMLCh* defaultValue = attDef.getValue();
if (defaultValue != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(defaultValue);
fInternalSubset.append(chDoubleQuote);
}
}
}
}
void AbstractDOMParser::doctypeComment
(
const XMLCh* const comment
)
{
if (fDocumentType->isIntSubsetReading())
{
if (comment != 0)
{
fInternalSubset.append(XMLUni::fgCommentString);
fInternalSubset.append(chSpace);
fInternalSubset.append(comment);
fInternalSubset.append(chSpace);
fInternalSubset.append(chDash);
fInternalSubset.append(chDash);
fInternalSubset.append(chCloseAngle);
}
}
}
void AbstractDOMParser::doctypeDecl
(
const DTDElementDecl& elemDecl
, const XMLCh* const publicId
, const XMLCh* const systemId
, const bool
, const bool
)
{
fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
fDocument->setDocumentType(fDocumentType);
}
void AbstractDOMParser::doctypePI
(
const XMLCh* const target
, const XMLCh* const data
)
{
if (fDocumentType->isIntSubsetReading())
{
//add these chars to internalSubset variable
fInternalSubset.append(chOpenAngle);
fInternalSubset.append(chQuestion);
fInternalSubset.append(target);
fInternalSubset.append(chSpace);
fInternalSubset.append(data);
fInternalSubset.append(chQuestion);
fInternalSubset.append(chCloseAngle);
}
}
void AbstractDOMParser::doctypeWhitespace
(
const XMLCh* const chars
, const unsigned int
)
{
if (fDocumentType->isIntSubsetReading())
fInternalSubset.append(chars);
}
void AbstractDOMParser::elementDecl
(
const DTDElementDecl& decl
, const bool
)
{
if (fDocumentType->isIntSubsetReading())
{
fInternalSubset.append(chOpenAngle);
fInternalSubset.append(chBang);
fInternalSubset.append(XMLUni::fgElemString);
fInternalSubset.append(chSpace);
fInternalSubset.append(decl.getFullName());
//get the ContentSpec information
const XMLCh* contentModel = decl.getFormattedContentModel();
if (contentModel != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(contentModel);
}
fInternalSubset.append(chCloseAngle);
}
}
void AbstractDOMParser::endAttList
(
const DTDElementDecl& elemDecl
)
{
if (fDocumentType->isIntSubsetReading())
{
//print the closing angle
fInternalSubset.append(chCloseAngle);
}
// 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
// DOM spec regarding creating element nodes & removing attributes with default values
// see DocumentTypeImpl
if (elemDecl.hasAttDefs())
{
XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
XMLAttDef* attr = 0;
DOMAttrImpl * insertAttr = 0;
DOMElement *elem = fDocument->createElement(elemDecl.getFullName());
DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
for(unsigned int i=0; i<defAttrs->getAttDefCount(); i++)
{
attr = &defAttrs->getAttDef(i);
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 = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
XMLBufBid bbQName(&fBufMgr);
XMLBuffer& buf = bbQName.getBuffer();
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 = (XMLCh*) fMemoryManager->allocate
(
(index + 1) * sizeof(XMLCh)
);//new XMLCh[index+1];
else
prefix = temp;
XMLString::subString(prefix ,qualifiedName, 0, index, fMemoryManager);
if (XMLString::equals(prefix,XMLNS))
buf.append(XMLUni::fgXMLNSURIName);
else
buf.append(XMLUni::fgXMLURIName);
if (index > 999)
fMemoryManager->deallocate(prefix);//delete [] prefix;
}
else {
// No prefix
if (XMLString::equals(qualifiedName,XMLNS))
buf.append(XMLUni::fgXMLNSURIName);
}
insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
buf.getRawBuffer(), // NameSpaceURI
qualifiedName); // qualified name
DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr);
if (remAttr)
remAttr->release();
}
else
{
// Namespaces is turned off...
insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr);
if (remAttr)
remAttr->release();
}
insertAttr->setValue(attr->getValue());
insertAttr->setSpecified(false);
}
}
DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl);
if (rem)
rem->release();
}
}
void AbstractDOMParser::endIntSubset()
{
fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
// the buffer shouldn't be released as it is reused in the next parse
// fBufMgr.releaseBuffer(fInternalSubset);
fDocumentType->fIntSubsetReading = false;
}
void AbstractDOMParser::endExtSubset()
{
}
void AbstractDOMParser::entityDecl
(
const DTDEntityDecl& entityDecl
, const bool
, const bool
)
{
DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName());
entity->setPublicId(entityDecl.getPublicId());
entity->setSystemId(entityDecl.getSystemId());
entity->setNotationName(entityDecl.getNotationName());
entity->setBaseURI(entityDecl.getBaseURI());
DOMEntityImpl *previousDef = (DOMEntityImpl *)
fDocumentType->getEntities()->setNamedItem( entity );
if (previousDef)
previousDef->release();
if (fDocumentType->isIntSubsetReading())
{
//add thes chars to internalSubset variable
fInternalSubset.append(chOpenAngle);
fInternalSubset.append(chBang);
fInternalSubset.append(XMLUni::fgEntityString);
fInternalSubset.append(chSpace);
fInternalSubset.append(entityDecl.getName());
const XMLCh* id = entity->getPublicId();
if (id != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgPubIDString);
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(id);
fInternalSubset.append(chDoubleQuote);
}
id = entity->getSystemId();
if (id != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgSysIDString);
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(id);
fInternalSubset.append(chDoubleQuote);
}
id = entity->getNotationName();
if (id != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgNDATAString);
fInternalSubset.append(chSpace);
fInternalSubset.append(id);
}
id = entityDecl.getValue();
if (id !=0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(id);
fInternalSubset.append(chDoubleQuote);
}
fInternalSubset.append(chCloseAngle);
}
}
void AbstractDOMParser::resetDocType()
{
fDocumentType = 0;
}
void AbstractDOMParser::notationDecl
(
const XMLNotationDecl& notDecl
, const bool
)
{
DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
notation->setPublicId(notDecl.getPublicId());
notation->setSystemId(notDecl.getSystemId());
notation->setBaseURI(notDecl.getBaseURI());
DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
if (rem)
rem->release();
if (fDocumentType->isIntSubsetReading())
{
//add thes chars to internalSubset variable
fInternalSubset.append(chOpenAngle);
fInternalSubset.append(chBang);
fInternalSubset.append(XMLUni::fgNotationString);
fInternalSubset.append(chSpace);
fInternalSubset.append(notDecl.getName());
const XMLCh* id = notation->getPublicId();
if (id != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgPubIDString);
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(id);
fInternalSubset.append(chDoubleQuote);
}
id = notation->getSystemId();
if (id != 0) {
fInternalSubset.append(chSpace);
fInternalSubset.append(XMLUni::fgSysIDString);
fInternalSubset.append(chSpace);
fInternalSubset.append(chDoubleQuote);
fInternalSubset.append(id);
fInternalSubset.append(chDoubleQuote);
}
fInternalSubset.append(chCloseAngle);
}
}
void AbstractDOMParser::startAttList
(
const DTDElementDecl& elemDecl
)
{
if (fDocumentType->isIntSubsetReading())
{
fInternalSubset.append(chOpenAngle);
fInternalSubset.append(chBang);
fInternalSubset.append(XMLUni::fgAttListString);
fInternalSubset.append(chSpace);
fInternalSubset.append(elemDecl.getFullName());
}
}
void AbstractDOMParser::startIntSubset()
{
fDocumentType->fIntSubsetReading = true;
}
void AbstractDOMParser::startExtSubset()
{
}
void AbstractDOMParser::TextDecl
(
const XMLCh* const versionStr
, const XMLCh* const encodingStr
)
{
if (fCurrentEntity) {
fCurrentEntity->setVersion(versionStr);
fCurrentEntity->setEncoding(encodingStr);
}
}
XERCES_CPP_NAMESPACE_END