AbstractDOMParser.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:53k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2002,2003 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /**
  57. *  This file contains code to build the DOM tree. It registers a document
  58. *  handler with the scanner. In these handler methods, appropriate DOM nodes
  59. *  are created and added to the DOM tree.
  60. *
  61. * $Id: AbstractDOMParser.cpp,v 1.44 2003/05/21 21:18:14 peiyongz Exp $
  62. *
  63. */
  64. // ---------------------------------------------------------------------------
  65. //  Includes
  66. // ---------------------------------------------------------------------------
  67. #include <xercesc/parsers/AbstractDOMParser.hpp>
  68. #include <xercesc/internal/XMLScannerResolver.hpp>
  69. #include <xercesc/internal/ElemStack.hpp>
  70. #include <xercesc/sax/EntityResolver.hpp>
  71. #include <xercesc/util/XMLUniDefs.hpp>
  72. #include <xercesc/framework/XMLNotationDecl.hpp>
  73. #include <xercesc/framework/XMLValidator.hpp>
  74. #include <xercesc/util/IOException.hpp>
  75. #include <xercesc/dom/DOMImplementation.hpp>
  76. #include <xercesc/dom/DOMElement.hpp>
  77. #include <xercesc/dom/impl/DOMAttrImpl.hpp>
  78. #include <xercesc/dom/DOMCDATASection.hpp>
  79. #include <xercesc/dom/DOMComment.hpp>
  80. #include <xercesc/dom/impl/DOMTextImpl.hpp>
  81. #include <xercesc/dom/impl/DOMDocumentImpl.hpp>
  82. #include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp>
  83. #include <xercesc/dom/DOMDocumentType.hpp>
  84. #include <xercesc/dom/impl/DOMElementImpl.hpp>
  85. #include <xercesc/dom/impl/DOMEntityImpl.hpp>
  86. #include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp>
  87. #include <xercesc/dom/impl/DOMNotationImpl.hpp>
  88. #include <xercesc/dom/DOMNamedNodeMap.hpp>
  89. #include <xercesc/dom/DOMProcessingInstruction.hpp>
  90. #include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
  91. #include <xercesc/dom/impl/DOMNodeIDMap.hpp>
  92. #include <xercesc/validators/common/ContentSpecNode.hpp>
  93. #include <xercesc/validators/common/GrammarResolver.hpp>
  94. #include <xercesc/validators/schema/SchemaSymbols.hpp>
  95. XERCES_CPP_NAMESPACE_BEGIN
  96. // ---------------------------------------------------------------------------
  97. //  AbstractDOMParser: Constructors and Destructor
  98. // ---------------------------------------------------------------------------
  99. AbstractDOMParser::AbstractDOMParser( XMLValidator* const valToAdopt
  100.                                     , MemoryManager* const manager) :
  101.   fCreateEntityReferenceNodes(true)
  102. , fIncludeIgnorableWhitespace(true)
  103. , fWithinElement(false)
  104. , fParseInProgress(false)
  105. , fCreateCommentNodes(true)
  106. , fDocumentAdoptedByUser(false)
  107. , fScanner(0)
  108. , fCurrentParent(0)
  109. , fCurrentNode(0)
  110. , fCurrentEntity(0)
  111. , fDocument(0)
  112. , fNodeStack(0)
  113. , fDocumentType(0)
  114. , fDocumentVector(0)
  115. , fGrammarResolver(0)
  116. , fURIStringPool(0)
  117. , fValidator(valToAdopt)
  118. , fMemoryManager(manager)
  119. , fBufMgr(manager)
  120. , fInternalSubset(fBufMgr.bidOnBuffer())
  121. {
  122.     try
  123.     {
  124.         initialize();
  125.     }
  126.     catch(...)
  127.     {
  128.        cleanUp();
  129.        throw;
  130.     }
  131. }
  132. AbstractDOMParser::~AbstractDOMParser()
  133. {
  134.     cleanUp();
  135. }
  136. // ---------------------------------------------------------------------------
  137. //  AbstractDOMParser: Initialize/CleanUp methods
  138. // ---------------------------------------------------------------------------
  139. void AbstractDOMParser::initialize()
  140. {
  141.     //  Create grammar resolver and string pool to pass to the scanner
  142.     fGrammarResolver = new (fMemoryManager) GrammarResolver(fMemoryManager);
  143.     fURIStringPool = new (fMemoryManager) XMLStringPool(109, fMemoryManager);
  144.     //  Create a scanner and tell it what validator to use. Then set us
  145.     //  as the document event handler so we can fill the DOM document.
  146.     fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fMemoryManager);
  147.     fScanner->setDocHandler(this);
  148.     fScanner->setDocTypeHandler(this);
  149.     fScanner->setGrammarResolver(fGrammarResolver);
  150.     fScanner->setURIStringPool(fURIStringPool);
  151.     fNodeStack = new (fMemoryManager) ValueStackOf<DOMNode*>(64, fMemoryManager);
  152.     this->reset();
  153. }
  154. void AbstractDOMParser::cleanUp()
  155. {
  156.     if (fDocumentVector)
  157.         delete fDocumentVector;
  158.     if (!fDocumentAdoptedByUser && fDocument)
  159.         fDocument->release();
  160.     delete fNodeStack;
  161.     delete fScanner;
  162.     delete fGrammarResolver;
  163.     delete fURIStringPool;
  164.     if (fValidator)
  165.         delete fValidator;
  166. }
  167. // ---------------------------------------------------------------------------
  168. //  AbstractDOMParser: Utilities
  169. // ---------------------------------------------------------------------------
  170. void AbstractDOMParser::reset()
  171. {
  172.     // if fDocument exists already, store the old pointer in the vector for deletion later
  173.     if (fDocument && !fDocumentAdoptedByUser) {
  174.         if (!fDocumentVector) {
  175.             // allocate the vector if not exists yet
  176.             fDocumentVector  = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ;
  177.         }
  178.         fDocumentVector->addElement(fDocument);
  179.     }
  180.     fDocument = 0;
  181.     resetDocType();
  182.     fCurrentParent   = 0;
  183.     fCurrentNode     = 0;
  184.     fCurrentEntity   = 0;
  185.     fParseInProgress = false;
  186.     fWithinElement   = false;
  187.     fDocumentAdoptedByUser = false;
  188.     fNodeStack->removeAllElements();
  189.     fInternalSubset.reset();
  190. };
  191. void AbstractDOMParser::resetPool()
  192. {
  193.     //  We cannot enter here while a regular parse is in progress.
  194.     if (fParseInProgress)
  195.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  196.     if (fDocumentVector)
  197.         fDocumentVector->removeAllElements();
  198.     if (!fDocumentAdoptedByUser && fDocument)
  199.         fDocument->release();
  200.     fDocument = 0;
  201. }
  202. bool AbstractDOMParser::isDocumentAdopted() const
  203. {
  204.     return fDocumentAdoptedByUser;
  205. }
  206. DOMDocument* AbstractDOMParser::adoptDocument()
  207. {
  208.     fDocumentAdoptedByUser = true;
  209.     return fDocument;
  210. }
  211. // ---------------------------------------------------------------------------
  212. //  AbstractDOMParser: Getter methods
  213. // ---------------------------------------------------------------------------
  214. DOMDocument* AbstractDOMParser::getDocument()
  215. {
  216.     return fDocument;
  217. }
  218. const XMLValidator& AbstractDOMParser::getValidator() const
  219. {
  220.     return *fScanner->getValidator();
  221. }
  222. bool AbstractDOMParser::getDoNamespaces() const
  223. {
  224.     return fScanner->getDoNamespaces();
  225. }
  226. bool AbstractDOMParser::getExitOnFirstFatalError() const
  227. {
  228.     return fScanner->getExitOnFirstFatal();
  229. }
  230. bool AbstractDOMParser::getValidationConstraintFatal() const
  231. {
  232.     return fScanner->getValidationConstraintFatal();
  233. }
  234. AbstractDOMParser::ValSchemes AbstractDOMParser::getValidationScheme() const
  235. {
  236.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  237.     if (scheme == XMLScanner::Val_Always)
  238.         return Val_Always;
  239.     else if (scheme == XMLScanner::Val_Never)
  240.         return Val_Never;
  241.     return Val_Auto;
  242. }
  243. bool AbstractDOMParser::getDoSchema() const
  244. {
  245.     return fScanner->getDoSchema();
  246. }
  247. bool AbstractDOMParser::getValidationSchemaFullChecking() const
  248. {
  249.     return fScanner->getValidationSchemaFullChecking();
  250. }
  251. int AbstractDOMParser::getErrorCount() const
  252. {
  253.     return fScanner->getErrorCount();
  254. }
  255. XMLCh* AbstractDOMParser::getExternalSchemaLocation() const
  256. {
  257.     return fScanner->getExternalSchemaLocation();
  258. }
  259. XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const
  260. {
  261.     return fScanner->getExternalNoNamespaceSchemaLocation();
  262. }
  263. SecurityManager* AbstractDOMParser::getSecurityManager() const
  264. {
  265.     return fScanner->getSecurityManager();
  266. }
  267. bool AbstractDOMParser::getLoadExternalDTD() const
  268. {
  269.     return fScanner->getLoadExternalDTD();
  270. }
  271. bool AbstractDOMParser::getCalculateSrcOfs() const
  272. {
  273.     return fScanner->getCalculateSrcOfs();
  274. }
  275. bool AbstractDOMParser::getStandardUriConformant() const
  276. {
  277.     return fScanner->getStandardUriConformant();
  278. }
  279. // ---------------------------------------------------------------------------
  280. //  AbstractDOMParser: Setter methods
  281. // ---------------------------------------------------------------------------
  282. void AbstractDOMParser::setDoNamespaces(const bool newState)
  283. {
  284.     fScanner->setDoNamespaces(newState);
  285. }
  286. void AbstractDOMParser::setExitOnFirstFatalError(const bool newState)
  287. {
  288.     fScanner->setExitOnFirstFatal(newState);
  289. }
  290. void AbstractDOMParser::setValidationConstraintFatal(const bool newState)
  291. {
  292.     fScanner->setValidationConstraintFatal(newState);
  293. }
  294. void AbstractDOMParser::setValidationScheme(const ValSchemes newScheme)
  295. {
  296.     if (newScheme == Val_Never)
  297.         fScanner->setValidationScheme(XMLScanner::Val_Never);
  298.     else if (newScheme == Val_Always)
  299.         fScanner->setValidationScheme(XMLScanner::Val_Always);
  300.     else
  301.         fScanner->setValidationScheme(XMLScanner::Val_Auto);
  302. }
  303. void AbstractDOMParser::setDoSchema(const bool newState)
  304. {
  305.     fScanner->setDoSchema(newState);
  306. }
  307. void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
  308. {
  309.     fScanner->setValidationSchemaFullChecking(schemaFullChecking);
  310. }
  311. void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
  312. {
  313.     fScanner->setExternalSchemaLocation(schemaLocation);
  314. }
  315. void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
  316. {
  317.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  318. }
  319. void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
  320. {
  321.     fScanner->setExternalSchemaLocation(schemaLocation);
  322. }
  323. void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
  324. {
  325.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  326. }
  327. void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager)
  328. {
  329.     // since this could impact various components, don't permit it to change
  330.     // during a parse
  331.     if (fParseInProgress)
  332.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  333.     fScanner->setSecurityManager(securityManager);
  334. }
  335. void AbstractDOMParser::setLoadExternalDTD(const bool newState)
  336. {
  337.     fScanner->setLoadExternalDTD(newState);
  338. }
  339. void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
  340. {
  341.     fScanner->setCalculateSrcOfs(newState);
  342. }
  343. void AbstractDOMParser::setStandardUriConformant(const bool newState)
  344. {
  345.     fScanner->setStandardUriConformant(newState);
  346. }
  347. void AbstractDOMParser::useScanner(const XMLCh* const scannerName)
  348. {
  349.     XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
  350.     (
  351.         scannerName
  352.         , fValidator
  353.         , fMemoryManager
  354.     );
  355.     if (tempScanner) {
  356.         tempScanner->setParseSettings(fScanner);
  357.         tempScanner->setGrammarResolver(fGrammarResolver);
  358.         tempScanner->setURIStringPool(fURIStringPool);
  359.         delete fScanner;
  360.         fScanner = tempScanner;
  361.     }
  362. }
  363. // ---------------------------------------------------------------------------
  364. //  AbstractDOMParser: Parsing methods
  365. // ---------------------------------------------------------------------------
  366. void AbstractDOMParser::parse(const InputSource& source)
  367. {
  368.     // Avoid multiple entrance
  369.     if (fParseInProgress)
  370.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  371.     try
  372.     {
  373.         fParseInProgress = true;
  374.         fScanner->scanDocument(source);
  375.         fParseInProgress = false;
  376.     }
  377.     catch(...)
  378.     {
  379.         fParseInProgress = false;
  380.         throw;
  381.     }
  382. }
  383. void AbstractDOMParser::parse(const XMLCh* const systemId)
  384. {
  385.     // Avoid multiple entrance
  386.     if (fParseInProgress)
  387.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  388.     try
  389.     {
  390.         fParseInProgress = true;
  391.         fScanner->scanDocument(systemId);
  392.         fParseInProgress = false;
  393.     }
  394.     catch(...)
  395.     {
  396.         fParseInProgress = false;
  397.         throw;
  398.     }
  399. }
  400. void AbstractDOMParser::parse(const char* const systemId)
  401. {
  402.     // Avoid multiple entrance
  403.     if (fParseInProgress)
  404.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  405.     try
  406.     {
  407.         fParseInProgress = true;
  408.         fScanner->scanDocument(systemId);
  409.         fParseInProgress = false;
  410.     }
  411.     catch(...)
  412.     {
  413.         fParseInProgress = false;
  414.         throw;
  415.     }
  416. }
  417. // ---------------------------------------------------------------------------
  418. //  AbstractDOMParser: Progressive parse methods
  419. // ---------------------------------------------------------------------------
  420. bool AbstractDOMParser::parseFirst( const XMLCh* const    systemId
  421.                                    ,       XMLPScanToken&  toFill)
  422. {
  423.     //
  424.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  425.     //  is in progress.
  426.     //
  427.     if (fParseInProgress)
  428.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  429.     return fScanner->scanFirst(systemId, toFill);
  430. }
  431. bool AbstractDOMParser::parseFirst( const char* const         systemId
  432.                                    ,       XMLPScanToken&      toFill)
  433. {
  434.     //
  435.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  436.     //  is in progress.
  437.     //
  438.     if (fParseInProgress)
  439.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  440.     return fScanner->scanFirst(systemId, toFill);
  441. }
  442. bool AbstractDOMParser::parseFirst( const InputSource& source
  443.                                    ,       XMLPScanToken&  toFill)
  444. {
  445.     //
  446.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  447.     //  is in progress.
  448.     //
  449.     if (fParseInProgress)
  450.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  451.     return fScanner->scanFirst(source, toFill);
  452. }
  453. bool AbstractDOMParser::parseNext(XMLPScanToken& token)
  454. {
  455.     return fScanner->scanNext(token);
  456. }
  457. void AbstractDOMParser::parseReset(XMLPScanToken& token)
  458. {
  459.     // Reset the scanner, and then reset the parser
  460.     fScanner->scanReset(token);
  461.     reset();
  462. }
  463. // ---------------------------------------------------------------------------
  464. //  AbstractDOMParser: Implementation of XMLDocumentHandler interface
  465. // ---------------------------------------------------------------------------
  466. void AbstractDOMParser::docCharacters(  const   XMLCh* const    chars
  467.                               , const unsigned int    length
  468.                               , const bool            cdataSection)
  469. {
  470.     // Ignore chars outside of content
  471.     if (!fWithinElement)
  472.         return;
  473.     // revisit.  Is it really safe to null-terminate here?
  474.     //                Does the scanner do it already?
  475.     //                If scanner goes up to the very end of an unterminated
  476.     //                buffer, we may be stepping on something bad here.
  477.     //           Probably best to modify the scanner to null terminate.
  478.     XMLCh savedChar = chars[length];
  479.     XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
  480.     ncChars[length] = 0;
  481.     if (cdataSection == true)
  482.     {
  483.         DOMCDATASection *node = fDocument->createCDATASection(chars);
  484.         fCurrentParent->appendChild(node);
  485.         fCurrentNode = node;
  486.     }
  487.     else
  488.     {
  489.         if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
  490.         {
  491.             DOMText *node = (DOMText *)fCurrentNode;
  492.             node->appendData(chars);
  493.         }
  494.         else
  495.         {
  496.             DOMText *node = fDocument->createTextNode(chars);
  497.             fCurrentParent->appendChild(node);
  498.             fCurrentNode = node;
  499.         }
  500.     }
  501.     ncChars[length] = savedChar;
  502.     return;
  503. }
  504. void AbstractDOMParser::docComment(const XMLCh* const comment)
  505. {
  506.     if (fCreateCommentNodes) {
  507.         DOMComment *dcom = fDocument->createComment(comment);
  508.         fCurrentParent->appendChild(dcom);
  509.         fCurrentNode = dcom;
  510.     }
  511. }
  512. void AbstractDOMParser::docPI(  const   XMLCh* const    target
  513.                       , const XMLCh* const    data)
  514. {
  515.     DOMProcessingInstruction *pi = fDocument->createProcessingInstruction
  516.         (
  517.         target
  518.         , data
  519.         );
  520.     fCurrentParent->appendChild(pi);
  521.     fCurrentNode = pi;
  522. }
  523. void AbstractDOMParser::endEntityReference(const XMLEntityDecl& entDecl)
  524. {
  525.     DOMEntityReferenceImpl *erImpl = 0;
  526.     DOMNode* firstChild = 0;
  527.     if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE) {
  528.         erImpl = (DOMEntityReferenceImpl *) fCurrentParent;
  529.         firstChild = erImpl->getFirstChild();
  530.     }
  531.     fCurrentParent = fNodeStack->pop();
  532.     if (!fCreateEntityReferenceNodes && erImpl && firstChild) {
  533.         DOMNode *kid, *next;
  534.         fCurrentNode   = fCurrentParent->getLastChild();
  535.         for (kid = firstChild; kid != 0; kid = next)
  536.         {
  537.             // If kid and fCurrentNode are both Text nodes (but _not_ CDATASection,
  538.             // which is a subclass of Text), they can be merged.
  539.             if (kid->getNodeType() == DOMNode::TEXT_NODE   &&
  540.                 fCurrentNode &&
  541.                 fCurrentNode->getNodeType() == DOMNode::TEXT_NODE )
  542.             {
  543.                 ((DOMTextImpl *) fCurrentNode)->appendData(((DOMTextImpl *) kid)->getData());
  544.             }
  545.             else {
  546.                 // append the child of erImpl to currentParent
  547.                 fCurrentNode = kid->cloneNode(true);
  548.                 fCurrentParent->appendChild(fCurrentNode);
  549.                 if (erImpl->getBaseURI()) {
  550.                     /**
  551.                      * Record baseURI information for the Element (by adding xml:base attribute)
  552.                      * or for the ProcessingInstruction (by setting a baseURI field)
  553.                      */
  554.                     if (fCurrentNode->getNodeType() == DOMNode::ELEMENT_NODE) {
  555.                         // if an element already has xml:base attribute
  556.                         // do nothing
  557.                         const XMLCh baseString[] =
  558.                         {
  559.                             chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
  560.                         };
  561.                         const XMLCh xmlBaseString[] =
  562.                         {
  563.                             chLatin_x, chLatin_m, chLatin_l, chColon, chLatin_b, chLatin_a, chLatin_s, chLatin_e, chNull
  564.                         };
  565.                         if (fScanner -> getDoNamespaces() && (((DOMElement*)fCurrentNode)->getAttributeNodeNS(DOMNodeImpl::getXmlURIString(), baseString) != 0)) {
  566.                             return;
  567.                         } else if (((DOMElement*)fCurrentNode)->getAttributeNode(xmlBaseString) != 0) {
  568.                             return;
  569.                         }
  570.                         // retrive the baseURI from the entity decl
  571.                         const XMLCh* baseURI = erImpl->getBaseURI();
  572.                         if (baseURI != 0 && !XMLString::equals(baseURI,fDocument->getDocumentURI())) {
  573.                             if (fScanner -> getDoNamespaces()) {
  574.                                 ((DOMElement*)fCurrentNode)->setAttributeNS(DOMNodeImpl::getXmlURIString(), baseString, baseURI);
  575.                             } else {
  576.                                 ((DOMElement*)fCurrentNode)->setAttribute(xmlBaseString, baseURI);
  577.                             }
  578.                         }
  579.                     }
  580.                     else if (fCurrentNode->getNodeType() == DOMNode::PROCESSING_INSTRUCTION_NODE) {
  581.                         ((DOMProcessingInstructionImpl*)fCurrentNode)->setBaseURI(erImpl->getBaseURI());
  582.                     }
  583.                 }
  584.             }
  585.             next = kid->getNextSibling();
  586.         }
  587.     }
  588.     else
  589.         fCurrentNode   = fCurrentParent;
  590.     if (erImpl)
  591.         erImpl->setReadOnly(true, true);
  592. }
  593. void AbstractDOMParser::endElement( const   XMLElementDecl&     elemDecl
  594.                            , const unsigned int        urlId
  595.                            , const bool                isRoot
  596.                            , const XMLCh* const        elemPrefix)
  597. {
  598.     fCurrentNode   = fCurrentParent;
  599.     fCurrentParent = fNodeStack->pop();
  600.     //validation is performed after the startElement event so we have to associate the info here
  601.     ((DOMElementImpl *)(fCurrentNode))->setTypeInfo(elemDecl.getDOMTypeInfoName(), elemDecl.getDOMTypeInfoUri());
  602.     // If we've hit the end of content, clear the flag
  603.     if (fNodeStack->empty())
  604.         fWithinElement = false;
  605. }
  606. void AbstractDOMParser::ignorableWhitespace(const   XMLCh* const    chars
  607.                                     , const unsigned int    length
  608.                                     , const bool            cdataSection)
  609. {
  610.     // Ignore chars before the root element
  611.     if (!fWithinElement || !fIncludeIgnorableWhitespace)
  612.         return;
  613.     // revisit.  Not safe to slam in a null like this.
  614.     XMLCh savedChar = chars[length];
  615.     XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
  616.     ncChars[length] = chNull;
  617.     if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
  618.     {
  619.         DOMText *node = (DOMText *)fCurrentNode;
  620.         node->appendData(chars);
  621.     }
  622.     else
  623.     {
  624.         DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars);
  625.         node->setIgnorableWhitespace(true);
  626.         fCurrentParent->appendChild(node);
  627.         fCurrentNode = node;
  628.     }
  629.     ncChars[length] = savedChar;
  630. }
  631. void AbstractDOMParser::resetDocument()
  632. {
  633.     //
  634.     //  The reset methods are called before a new parse event occurs.
  635.     //  Reset this parsers state to clear out anything that may be left
  636.     //  from a previous use, in particular the DOM document itself.
  637.     //
  638.     this->reset();
  639. }
  640. void AbstractDOMParser::startDocument()
  641. {
  642.     fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument();
  643.     // Just set the document as the current parent and current node
  644.     fCurrentParent = fDocument;
  645.     fCurrentNode   = fDocument;
  646.     // set DOM error checking off
  647.     fDocument->setErrorChecking(false);
  648.     fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
  649.     fDocument->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
  650. }
  651. void AbstractDOMParser::endDocument()
  652. {
  653.     // set DOM error checking back on
  654.     fDocument->setErrorChecking(true);
  655.     // DOM L2 does not support editing DocumentType nodes
  656.     if (fDocumentType && fScanner -> getDoNamespaces())
  657.         fDocumentType->setReadOnly(true, true);
  658. }
  659. void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
  660.                              , const unsigned int            urlId
  661.                              , const XMLCh* const            elemPrefix
  662.                              , const RefVectorOf<XMLAttr>&   attrList
  663.                              , const unsigned int            attrCount
  664.                              , const bool                    isEmpty
  665.                              , const bool                    isRoot)
  666. {
  667.     DOMElement     *elem;
  668.     DOMElementImpl *elemImpl;
  669.     static const XMLCh XMLNS[] = {
  670.     chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull
  671.     };
  672.     static const XMLCh XSI[] = {
  673.     chLatin_x, chLatin_s, chLatin_i, chNull
  674.     };
  675.     //get the list for use in the loop
  676.     XMLAttDefList* defAttrs = 0;
  677.     if(elemDecl.hasAttDefs()) {
  678.         defAttrs = &elemDecl.getAttDefList();
  679.     }
  680.     if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on
  681.         const XMLCh* namespaceURI = 0;
  682.         if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  683.             namespaceURI = fScanner->getURIText(urlId); //get namespaceURI
  684.             if (elemPrefix && *elemPrefix) {
  685.                 XMLBufBid elemQName(&fBufMgr);
  686.                 elemQName.set(elemPrefix);
  687.                 elemQName.append(chColon);
  688.                 elemQName.append(elemDecl.getBaseName());
  689.                 elem = createElementNSNode(namespaceURI, elemQName.getRawBuffer());
  690.             }
  691.             else { 
  692.                 elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
  693.             }
  694.         } 
  695.         else {
  696.             elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
  697.         }
  698.         elemImpl = (DOMElementImpl *) elem;
  699.         for (unsigned int index = 0; index < attrCount; ++index) {
  700.             const XMLAttr* oneAttrib = attrList.elementAt(index);
  701.             unsigned int attrURIId = oneAttrib -> getURIId();
  702.             namespaceURI = 0;
  703.             if (XMLString::equals(oneAttrib -> getName(), XMLNS))    //for xmlns=...
  704.                 attrURIId = fScanner->getXMLNSNamespaceId();
  705.             if (attrURIId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  706.                 namespaceURI = fScanner->getURIText(attrURIId);   //get namespaceURI
  707.             }
  708.             //  revisit.  Optimize to init the named node map to the
  709.             //            right size up front.
  710.             DOMAttrImpl *attr = (DOMAttrImpl *)
  711.                 fDocument->createAttributeNS(namespaceURI, oneAttrib->getQName());
  712.             attr->setValue(oneAttrib -> getValue());
  713.             DOMNode* remAttr = elemImpl->setAttributeNodeNS(attr);
  714.             if (remAttr)
  715.                 remAttr->release();
  716.             //DOMAttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(),
  717.             //    oneAttrib -> getValue());
  718.             // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  719.             //   that is constructed for use by GetElementByID().
  720.             //
  721.             if (oneAttrib->getType()==XMLAttDef::ID)
  722.             {
  723.                 if (fDocument->fNodeIDMap == 0)
  724.                     fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
  725.                 fDocument->fNodeIDMap->add(attr);
  726.                 attr->fNode.isIdAttr(true);
  727.             }
  728.             attr->setSpecified(oneAttrib->getSpecified());
  729.             XMLAttDef *attDef = 0;
  730.             if(defAttrs != 0)
  731.                 attDef = defAttrs->findAttDef(attrURIId, oneAttrib->getQName());
  732.             if(attDef != 0) {
  733.                 attr->setTypeInfo(attDef->getDOMTypeInfoName(), attDef->getDOMTypeInfoUri());
  734.                 attDef->reset();
  735.             }
  736.             else {
  737.                 const XMLCh *name = oneAttrib->getName();
  738.                 if (XMLString::equals(oneAttrib->getPrefix(), XSI)) {
  739.                     if(XMLString::equals(name, SchemaSymbols::fgXSI_TYPE)) {
  740.                         attr->setTypeInfo(SchemaSymbols::fgDT_QNAME, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  741.                     }
  742.                     else if(XMLString::equals(name, SchemaSymbols::fgATT_NILL)) {
  743.                         attr->setTypeInfo(SchemaSymbols::fgDT_BOOLEAN, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  744.                     }
  745.                     else if(XMLString::equals(name, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION)) {
  746.                         attr->setTypeInfo(SchemaSymbols::fgDT_ANYURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  747.                     }
  748.                 }
  749.                 else {
  750.                     //for normal ns attrs
  751.                     attr->setTypeInfo(SchemaSymbols::fgDT_ANYURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  752.                 }
  753.             }
  754.         }
  755.     }
  756.     else {    //DOM Level 1
  757.         elem = fDocument->createElement(elemDecl.getFullName());
  758.         elemImpl = (DOMElementImpl *) elem;
  759. for (unsigned int index = 0; index < attrCount; ++index) {
  760. const XMLAttr* oneAttrib = attrList.elementAt(index);
  761.             //AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
  762.             DOMAttrImpl *attr = (DOMAttrImpl *)
  763.                 fDocument->createAttribute(oneAttrib->getName());
  764.             attr->setValue(oneAttrib -> getValue());
  765.             DOMNode* rem = elemImpl->setAttributeNode(attr);
  766.             if (rem)
  767.                 rem->release();
  768. attr->setSpecified(oneAttrib->getSpecified());
  769. // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  770. //   that is constructed for use by GetElementByID().
  771. //
  772. if (oneAttrib->getType()==XMLAttDef::ID)
  773. {
  774.                 if (fDocument->fNodeIDMap == 0)
  775.                     fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
  776.                 fDocument->fNodeIDMap->add(attr);
  777.                 attr->fNode.isIdAttr(true);
  778.             }
  779.             XMLAttDef *attDef = 0;
  780.             if(defAttrs != 0)
  781.                 attDef = defAttrs->findAttDef(oneAttrib -> getURIId(), oneAttrib->getQName());
  782.             if(attDef != 0) {
  783.                 attr->setTypeInfo(attDef->getDOMTypeInfoName(), attDef->getDOMTypeInfoUri());
  784.                 attDef->reset();
  785.             }
  786.         }
  787.     }
  788.     // set up the default attributes
  789. if (defAttrs != 0)
  790. {
  791.         XMLAttDef* attr = 0;
  792.         DOMAttrImpl * insertAttr = 0;
  793.         while (defAttrs->hasMoreElements())
  794.         {
  795.             attr = &defAttrs->nextElement();
  796.             const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
  797.             if ((defType == XMLAttDef::Default)
  798.             ||  (defType == XMLAttDef::Fixed))
  799.             {
  800.                 if (fScanner->getDoNamespaces())
  801.                 {
  802.                     // DOM Level 2 wants all namespace declaration attributes
  803.                     // to be bound to "http://www.w3.org/2000/xmlns/"
  804.                     // So as long as the XML parser doesn't do it, it needs to
  805.                     // done here.
  806.                     const XMLCh* qualifiedName = attr->getFullName();
  807.                     XMLBufBid bbPrefixQName(&fBufMgr);
  808.                     XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
  809.                     int colonPos = -1;
  810.                     unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);
  811.                     const XMLCh* namespaceURI = 0;
  812.                     if (XMLString::equals(qualifiedName, XMLNS))    //for xmlns=...
  813.                         uriId = fScanner->getXMLNSNamespaceId();
  814.                     if (uriId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  815.                         namespaceURI = fScanner->getURIText(uriId);
  816.                     }
  817.                     insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
  818.                                                                               namespaceURI,     // NameSpaceURI
  819.                                                                               qualifiedName);   // qualified name
  820.                     DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
  821.                     if (remAttr)
  822.                         remAttr->release();
  823.                     if (attr->getValue() != 0)
  824.                     {
  825.                         insertAttr->setValue(attr->getValue());
  826.                         insertAttr->setSpecified(false);
  827.                     }
  828.                 }
  829.                 else
  830.                 {
  831.                     // Namespaces is turned off...
  832.                     insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
  833.                     DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
  834.                     if (remAttr)
  835.                         remAttr->release();
  836.                     //need to do this before the get as otherwise we overwrite any value in the attr
  837.                     if (attr->getValue() != 0)
  838.                     {
  839.                         insertAttr->setValue(attr->getValue());
  840.                         insertAttr->setSpecified(false);
  841.                     }
  842.                 }
  843.                 insertAttr->setTypeInfo(attr->getDOMTypeInfoName(), attr->getDOMTypeInfoUri());
  844.             }
  845.             insertAttr = 0;
  846.             attr->reset();
  847.         }
  848.     }
  849.     fCurrentParent->appendChild(elem);
  850.     fNodeStack->push(fCurrentParent);
  851.     fCurrentParent = elem;
  852.     fCurrentNode = elem;
  853.     fWithinElement = true;
  854.     // If an empty element, do end right now (no endElement() will be called)
  855.     if (isEmpty)
  856.         endElement(elemDecl, urlId, isRoot, elemPrefix);
  857. }
  858. void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
  859. {
  860.     const XMLCh * entName = entDecl.getName();
  861.     DOMNamedNodeMap *entities = fDocumentType->getEntities();
  862.     DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName);
  863.     if (entity)
  864.         entity->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
  865.     fCurrentEntity = entity;
  866.     DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);
  867.     //set the readOnly flag to false before appending node, will be reset in endEntityReference
  868.     DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
  869.     erImpl->setReadOnly(false, true);
  870.     if (fCreateEntityReferenceNodes == true)
  871.     {
  872.         fCurrentParent->appendChild(er);
  873.     }
  874.     fNodeStack->push(fCurrentParent);
  875.     fCurrentParent = er;
  876.     fCurrentNode = er;
  877.     // this entityRef needs to be stored in Entity map too.
  878.     // We'd decide later whether the entity nodes should be created by a
  879.     // separated method in parser or not. For now just stick it in if
  880.     // the ref nodes are created
  881.     if (entity)
  882.         entity->setEntityRef(er);
  883. }
  884. void AbstractDOMParser::XMLDecl(const   XMLCh* const version
  885.                                 , const XMLCh* const encoding
  886.                                 , const XMLCh* const standalone
  887.                                 , const XMLCh* const actualEncStr)
  888. {
  889.     fDocument->setStandalone(XMLString::equals(XMLUni::fgYesString, standalone));
  890.     fDocument->setVersion(version);
  891.     fDocument->setEncoding(encoding);
  892.     fDocument->setActualEncoding(actualEncStr);
  893. }
  894. // ---------------------------------------------------------------------------
  895. //  AbstractDOMParser: Helper methods
  896. // ---------------------------------------------------------------------------
  897. DOMElement* AbstractDOMParser::createElementNSNode(const XMLCh *namespaceURI,
  898.                                                    const XMLCh *qualifiedName)
  899. {
  900.     return fDocument->createElementNS(namespaceURI, qualifiedName);
  901. }
  902. // ---------------------------------------------------------------------------
  903. //  AbstractDOMParser: Deprecated methods
  904. // ---------------------------------------------------------------------------
  905. bool AbstractDOMParser::getDoValidation() const
  906. {
  907.     //
  908.     //  We don't want to tie the public parser classes to the enum used
  909.     //  by the scanner, so we use a separate one and map.
  910.     //
  911.     //  DON'T mix the new and old methods!!
  912.     //
  913.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  914.     if (scheme == XMLScanner::Val_Always)
  915.         return true;
  916.     return false;
  917. }
  918. void AbstractDOMParser::setDoValidation(const bool newState)
  919. {
  920.     fScanner->setDoValidation
  921.     (
  922.         newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
  923.     );
  924. }
  925. //doctypehandler interfaces
  926. void AbstractDOMParser::attDef
  927. (
  928.     const   DTDElementDecl&     elemDecl
  929.     , const DTDAttDef&          attDef
  930.     , const bool                ignoring
  931. )
  932. {
  933.     if (fDocumentType->isIntSubsetReading())
  934.     {
  935.         if (elemDecl.hasAttDefs())
  936.         {
  937.             fInternalSubset.append(attDef.getFullName());
  938.             // Get the type and display it
  939.             const XMLAttDef::AttTypes type = attDef.getType();
  940.             switch(type)
  941.             {
  942.             case XMLAttDef::CData :
  943.                 fInternalSubset.append(chSpace);
  944.                 fInternalSubset.append(XMLUni::fgCDATAString);
  945.                 break;
  946.             case XMLAttDef::ID :
  947.                 fInternalSubset.append(chSpace);
  948.                 fInternalSubset.append(XMLUni::fgIDString);
  949.                 break;
  950.             case XMLAttDef::IDRef :
  951.                 fInternalSubset.append(chSpace);
  952.                 fInternalSubset.append(XMLUni::fgIDRefString);
  953.                 break;
  954.             case XMLAttDef::IDRefs :
  955.                 fInternalSubset.append(chSpace);
  956.                 fInternalSubset.append(XMLUni::fgIDRefsString);
  957.                 break;
  958.             case XMLAttDef::Entity :
  959.                 fInternalSubset.append(chSpace);
  960.                 fInternalSubset.append(XMLUni::fgEntityString);
  961.                 break;
  962.             case XMLAttDef::Entities :
  963.                 fInternalSubset.append(chSpace);
  964.                 fInternalSubset.append(XMLUni::fgEntitiesString);
  965.                 break;
  966.             case XMLAttDef::NmToken :
  967.                 fInternalSubset.append(chSpace);
  968.                 fInternalSubset.append(XMLUni::fgNmTokenString);
  969.                 break;
  970.             case XMLAttDef::NmTokens :
  971.                 fInternalSubset.append(chSpace);
  972.                 fInternalSubset.append(XMLUni::fgNmTokensString);
  973.                 break;
  974.             case XMLAttDef::Notation :
  975.                 fInternalSubset.append(chSpace);
  976.                 fInternalSubset.append(XMLUni::fgNotationString);
  977.                 break;
  978.             case XMLAttDef::Enumeration :
  979.                 fInternalSubset.append(chSpace);
  980.                 const XMLCh* enumString = attDef.getEnumeration();
  981.                 int length = XMLString::stringLen(enumString);
  982.                 if (length > 0) {
  983.                     fInternalSubset.append(chOpenParen );
  984.                     for(int i=0; i<length; i++) {
  985.                         if (enumString[i] == chSpace)
  986.                             fInternalSubset.append(chPipe);
  987.                         else
  988.                             fInternalSubset.append(enumString[i]);
  989.                     }
  990.                     fInternalSubset.append(chCloseParen);
  991.                 }
  992.                 break;
  993.             }
  994.             //get te default types of the attlist
  995.             const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
  996.             switch(def)
  997.             {
  998.             case XMLAttDef::Required :
  999.                 fInternalSubset.append(chSpace);
  1000.                 fInternalSubset.append(XMLUni::fgRequiredString);
  1001.                 break;
  1002.             case XMLAttDef::Implied :
  1003.                 fInternalSubset.append(chSpace);
  1004.                 fInternalSubset.append(XMLUni::fgImpliedString);
  1005.                 break;
  1006.             case XMLAttDef::Fixed :
  1007.                 fInternalSubset.append(chSpace);
  1008.                 fInternalSubset.append(XMLUni::fgFixedString);
  1009.                 break;
  1010.             }
  1011.             const XMLCh* defaultValue = attDef.getValue();
  1012.             if (defaultValue != 0) {
  1013.                 fInternalSubset.append(chSpace);
  1014.                 fInternalSubset.append(chDoubleQuote);
  1015.                 fInternalSubset.append(defaultValue);
  1016.                 fInternalSubset.append(chDoubleQuote);
  1017.             }
  1018.         }
  1019.     }
  1020. }
  1021. void AbstractDOMParser::doctypeComment
  1022. (
  1023.     const   XMLCh* const    comment
  1024. )
  1025. {
  1026.     if (fDocumentType->isIntSubsetReading())
  1027.     {
  1028.         if (comment != 0)
  1029.         {
  1030.             fInternalSubset.append(XMLUni::fgCommentString);
  1031.             fInternalSubset.append(chSpace);
  1032.             fInternalSubset.append(comment);
  1033.             fInternalSubset.append(chSpace);
  1034.             fInternalSubset.append(chDash);
  1035.             fInternalSubset.append(chDash);
  1036.             fInternalSubset.append(chCloseAngle);
  1037.         }
  1038.     }
  1039. }
  1040. void AbstractDOMParser::doctypeDecl
  1041. (
  1042.     const   DTDElementDecl& elemDecl
  1043.     , const XMLCh* const    publicId
  1044.     , const XMLCh* const    systemId
  1045.     , const bool            hasIntSubset
  1046.     , const bool            hasExtSubset
  1047. )
  1048. {
  1049.     fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
  1050.     fDocument->setDocumentType(fDocumentType);
  1051. }
  1052. void AbstractDOMParser::doctypePI
  1053. (
  1054.     const   XMLCh* const    target
  1055.     , const XMLCh* const    data
  1056. )
  1057. {
  1058.     if (fDocumentType->isIntSubsetReading())
  1059.     {
  1060.         //add these chars to internalSubset variable
  1061.         fInternalSubset.append(chOpenAngle);
  1062.         fInternalSubset.append(chQuestion);
  1063.         fInternalSubset.append(target);
  1064.         fInternalSubset.append(chSpace);
  1065.         fInternalSubset.append(data);
  1066.         fInternalSubset.append(chQuestion);
  1067.         fInternalSubset.append(chCloseAngle);
  1068.     }
  1069. }
  1070. void AbstractDOMParser::doctypeWhitespace
  1071. (
  1072.     const   XMLCh* const    chars
  1073.     , const unsigned int    length
  1074. )
  1075. {
  1076.     if (fDocumentType->isIntSubsetReading())
  1077.         fInternalSubset.append(chars);
  1078. }
  1079. void AbstractDOMParser::elementDecl
  1080. (
  1081.     const   DTDElementDecl& decl
  1082.     , const bool            isIgnored
  1083. )
  1084. {
  1085.     if (fDocumentType->isIntSubsetReading())
  1086.     {
  1087.         fInternalSubset.append(chOpenAngle);
  1088.         fInternalSubset.append(chBang);
  1089.         fInternalSubset.append(XMLUni::fgElemString);
  1090.         fInternalSubset.append(chSpace);
  1091.         fInternalSubset.append(decl.getFullName());
  1092.         //get the ContentSpec information
  1093.         const XMLCh* contentModel = decl.getFormattedContentModel();
  1094.         if (contentModel != 0) {
  1095.             fInternalSubset.append(chSpace);
  1096.             fInternalSubset.append(contentModel);
  1097.         }
  1098.         fInternalSubset.append(chCloseAngle);
  1099.     }
  1100. }
  1101. void AbstractDOMParser::endAttList
  1102. (
  1103.     const   DTDElementDecl& elemDecl
  1104. )
  1105. {
  1106.     if (fDocumentType->isIntSubsetReading())
  1107.     {
  1108.         //print the closing angle
  1109.         fInternalSubset.append(chCloseAngle);
  1110.     }
  1111. // this section sets up default attributes.
  1112. // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
  1113. // default attribute data attached to the document is used to conform to the
  1114. // DOM spec regarding creating element nodes & removing attributes with default values
  1115. // see DocumentTypeImpl
  1116. if (elemDecl.hasAttDefs())
  1117. {
  1118.         XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
  1119.         XMLAttDef* attr = 0;
  1120.         DOMAttrImpl * insertAttr = 0;
  1121.         DOMElement     *elem  = fDocument->createElement(elemDecl.getFullName());
  1122.         DOMElementImpl *elemImpl = (DOMElementImpl *) elem;
  1123. while (defAttrs->hasMoreElements())
  1124.         {
  1125.             attr = &defAttrs->nextElement();
  1126.             if (attr->getValue() != 0)
  1127.             {
  1128.                 if (fScanner->getDoNamespaces())
  1129.                 {
  1130.                     // DOM Level 2 wants all namespace declaration attributes
  1131.                     // to be bound to "http://www.w3.org/2000/xmlns/"
  1132.                     // So as long as the XML parser doesn't do it, it needs to
  1133.                     // done here.
  1134.                     const XMLCh* qualifiedName = attr->getFullName();
  1135.                     int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
  1136.                     XMLBufBid bbQName(&fBufMgr);
  1137.                     XMLBuffer& buf = bbQName.getBuffer();
  1138.                     static const XMLCh XMLNS[] = {
  1139.                         chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
  1140.                     if (index > 0) {
  1141.                         // there is prefix
  1142.                         // map to XML URI for all cases except when prefix == "xmlns"
  1143.                         XMLCh* prefix;
  1144.                         XMLCh temp[1000];
  1145.                         if (index > 999)
  1146.                             prefix = (XMLCh*) fMemoryManager->allocate
  1147.                             (
  1148.                                 (index + 1) * sizeof(XMLCh)
  1149.                             );//new XMLCh[index+1];
  1150.                         else
  1151.                             prefix = temp;
  1152.                         XMLString::subString(prefix ,qualifiedName, 0, index);
  1153.                         if (XMLString::equals(prefix,XMLNS))
  1154.                             buf.append(XMLUni::fgXMLNSURIName);
  1155.                         else
  1156.                             buf.append(XMLUni::fgXMLURIName);
  1157.                         if (index > 999)
  1158.                             fMemoryManager->deallocate(prefix);//delete [] prefix;
  1159.                     }
  1160.                     else {
  1161.                         //   No prefix
  1162.                         if (XMLString::equals(qualifiedName,XMLNS))
  1163.                             buf.append(XMLUni::fgXMLNSURIName);
  1164.                     }
  1165.                     insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
  1166.                        buf.getRawBuffer(),     // NameSpaceURI
  1167.                        qualifiedName);   // qualified name
  1168.                     DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr);
  1169.                     if (remAttr)
  1170.                         remAttr->release();
  1171.                 }
  1172.                 else
  1173.                 {
  1174.                     // Namespaces is turned off...
  1175.                     insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
  1176.                     DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr);
  1177.                     if (remAttr)
  1178.                         remAttr->release();
  1179.                 }
  1180.                 insertAttr->setValue(attr->getValue());
  1181.                 insertAttr->setSpecified(false);
  1182.             }
  1183.         }
  1184.         DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl);
  1185.         if (rem)
  1186.             rem->release();
  1187.     }
  1188. }
  1189. void AbstractDOMParser::endIntSubset()
  1190. {
  1191.     fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
  1192.     // the buffer shouldn't be released as it is reused in the next parse
  1193.     // fBufMgr.releaseBuffer(fInternalSubset);
  1194.     fDocumentType->fIntSubsetReading = false;
  1195. }
  1196. void AbstractDOMParser::endExtSubset()
  1197. {
  1198. }
  1199. void AbstractDOMParser::entityDecl
  1200. (
  1201.     const   DTDEntityDecl&  entityDecl
  1202.     , const bool            isPEDecl
  1203.     , const bool            isIgnored
  1204. )
  1205. {
  1206.     DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName());
  1207.     entity->setPublicId(entityDecl.getPublicId());
  1208.     entity->setSystemId(entityDecl.getSystemId());
  1209.     entity->setNotationName(entityDecl.getNotationName());
  1210.     entity->setBaseURI(entityDecl.getBaseURI());
  1211.     DOMEntityImpl *previousDef = (DOMEntityImpl *)
  1212.     fDocumentType->getEntities()->setNamedItem( entity );
  1213.     if (previousDef)
  1214.         previousDef->release();
  1215.     if (fDocumentType->isIntSubsetReading())
  1216.     {
  1217.         //add thes chars to internalSubset variable
  1218.         fInternalSubset.append(chOpenAngle);
  1219.         fInternalSubset.append(chBang);
  1220.         fInternalSubset.append(XMLUni::fgEntityString);
  1221.         fInternalSubset.append(chSpace);
  1222.         fInternalSubset.append(entityDecl.getName());
  1223.         const XMLCh* id = entity->getPublicId();
  1224.         if (id != 0) {
  1225.             fInternalSubset.append(chSpace);
  1226.             fInternalSubset.append(XMLUni::fgPubIDString);
  1227.             fInternalSubset.append(chSpace);
  1228.             fInternalSubset.append(chDoubleQuote);
  1229.             fInternalSubset.append(id);
  1230.             fInternalSubset.append(chDoubleQuote);
  1231.         }
  1232.         id = entity->getSystemId();
  1233.         if (id != 0) {
  1234.             fInternalSubset.append(chSpace);
  1235.             fInternalSubset.append(XMLUni::fgSysIDString);
  1236.             fInternalSubset.append(chSpace);
  1237.             fInternalSubset.append(chDoubleQuote);
  1238.             fInternalSubset.append(id);
  1239.             fInternalSubset.append(chDoubleQuote);
  1240.         }
  1241.         id = entity->getNotationName();
  1242.         if (id != 0) {
  1243.             fInternalSubset.append(chSpace);
  1244.             fInternalSubset.append(XMLUni::fgNDATAString);
  1245.             fInternalSubset.append(chSpace);
  1246.             fInternalSubset.append(id);
  1247.         }
  1248.         id = entityDecl.getValue();
  1249.         if (id !=0) {
  1250.             fInternalSubset.append(chSpace);
  1251.             fInternalSubset.append(chDoubleQuote);
  1252.             fInternalSubset.append(id);
  1253.             fInternalSubset.append(chDoubleQuote);
  1254.         }
  1255.         fInternalSubset.append(chCloseAngle);
  1256.     }
  1257. }
  1258. void AbstractDOMParser::resetDocType()
  1259. {
  1260. fDocumentType = 0;
  1261. }
  1262. void AbstractDOMParser::notationDecl
  1263. (
  1264.     const   XMLNotationDecl&    notDecl
  1265.     , const bool                isIgnored
  1266. )
  1267. {
  1268.     DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
  1269.     notation->setPublicId(notDecl.getPublicId());
  1270.     notation->setSystemId(notDecl.getSystemId());
  1271.     notation->setBaseURI(notDecl.getBaseURI());
  1272.     DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
  1273.     if (rem)
  1274.         rem->release();
  1275.     if (fDocumentType->isIntSubsetReading())
  1276.     {
  1277.         //add thes chars to internalSubset variable
  1278.         fInternalSubset.append(chOpenAngle);
  1279.         fInternalSubset.append(chBang);
  1280.         fInternalSubset.append(XMLUni::fgNotationString);
  1281.         fInternalSubset.append(chSpace);
  1282.         fInternalSubset.append(notDecl.getName());
  1283.         const XMLCh* id = notation->getPublicId();
  1284.         if (id != 0) {
  1285.             fInternalSubset.append(chSpace);
  1286.             fInternalSubset.append(XMLUni::fgPubIDString);
  1287.             fInternalSubset.append(chSpace);
  1288.             fInternalSubset.append(chDoubleQuote);
  1289.             fInternalSubset.append(id);
  1290.             fInternalSubset.append(chDoubleQuote);
  1291.         }
  1292.         id = notation->getSystemId();
  1293.         if (id != 0) {
  1294.             fInternalSubset.append(chSpace);
  1295.             fInternalSubset.append(XMLUni::fgSysIDString);
  1296.             fInternalSubset.append(chSpace);
  1297.             fInternalSubset.append(chDoubleQuote);
  1298.             fInternalSubset.append(id);
  1299.             fInternalSubset.append(chDoubleQuote);
  1300.         }
  1301.         fInternalSubset.append(chCloseAngle);
  1302.     }
  1303. }
  1304. void AbstractDOMParser::startAttList
  1305. (
  1306.     const   DTDElementDecl& elemDecl
  1307. )
  1308. {
  1309.     if (fDocumentType->isIntSubsetReading())
  1310.     {
  1311.         fInternalSubset.append(chOpenAngle);
  1312.         fInternalSubset.append(chBang);
  1313.         fInternalSubset.append(XMLUni::fgAttListString);
  1314.         fInternalSubset.append(chSpace);
  1315.         fInternalSubset.append(elemDecl.getFullName());
  1316.     }
  1317. }
  1318. void AbstractDOMParser::startIntSubset()
  1319. {
  1320. fDocumentType->fIntSubsetReading = true;
  1321. }
  1322. void AbstractDOMParser::startExtSubset()
  1323. {
  1324. }
  1325. void AbstractDOMParser::TextDecl
  1326. (
  1327.     const   XMLCh* const    versionStr
  1328.     , const XMLCh* const    encodingStr
  1329. )
  1330. {
  1331.     if (fCurrentEntity) {
  1332.         fCurrentEntity->setVersion(versionStr);
  1333.         fCurrentEntity->setEncoding(encodingStr);
  1334.     }
  1335. }
  1336. XERCES_CPP_NAMESPACE_END