DOMParser.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:38k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2001 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) 1999, 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: DOMParser.cpp,v 1.56 2001/11/20 18:51:44 tng Exp $
  62. *
  63. */
  64. // ---------------------------------------------------------------------------
  65. //  Includes
  66. // ---------------------------------------------------------------------------
  67. #include <sax/EntityResolver.hpp>
  68. #include <util/XMLUniDefs.hpp>
  69. #include <sax/ErrorHandler.hpp>
  70. #include <sax/SAXParseException.hpp>
  71. #include <framework/XMLNotationDecl.hpp>
  72. #include <util/IOException.hpp>
  73. #include <internal/XMLScanner.hpp>
  74. #include <validators/DTD/DTDValidator.hpp>
  75. #include <parsers/DOMParser.hpp>
  76. #include <dom/ElementImpl.hpp>
  77. #include <dom/AttrImpl.hpp>
  78. #include <dom/AttrNSImpl.hpp>
  79. #include <dom/TextImpl.hpp>
  80. #include <dom/DocumentImpl.hpp>
  81. #include <dom/DocumentTypeImpl.hpp>
  82. #include <dom/EntityImpl.hpp>
  83. #include <dom/NotationImpl.hpp>
  84. #include <dom/NamedNodeMapImpl.hpp>
  85. #include <dom/NodeIDMap.hpp>
  86. #include <validators/common/ContentSpecNode.hpp>
  87. #include <validators/DTD/DTDAttDefList.hpp>
  88. // ---------------------------------------------------------------------------
  89. //  DOMParser: Constructors and Destructor
  90. // ---------------------------------------------------------------------------
  91. DOMParser::DOMParser(XMLValidator* const valToAdopt) :
  92. fErrorHandler(0)
  93. , fEntityResolver(0)
  94. , fCreateEntityReferenceNodes(false)
  95. , fToCreateXMLDeclTypeNode(false)
  96. , fIncludeIgnorableWhitespace(true)
  97. , fNodeStack(0)
  98. , fScanner(0)
  99. {
  100.     //
  101.     //  Create a scanner and tell it what validator to use. Then set us
  102.     //  as the document event handler so we can fill the DOM document.
  103.     //
  104.     fScanner = new XMLScanner(valToAdopt);
  105.     fScanner->setDocHandler(this);
  106.     fScanner->setDocTypeHandler(this);
  107.     fNodeStack = new ValueStackOf<DOM_Node>(64);
  108.     this->reset();
  109. }
  110. DOMParser::~DOMParser()
  111. {
  112.     delete fNodeStack;
  113.     delete fScanner;
  114. }
  115. void DOMParser::reset()
  116. {
  117.     //
  118.     //  Note: DOM Documents are reference counted. Doing this assignment
  119.     //  will cause the old one to go away unless application code is also
  120.     //  holding a reference to it.
  121.     //
  122.     fDocument = DOM_Document::createDocument();
  123.     resetDocType();
  124.     fCurrentParent   = 0;
  125.     fCurrentNode     = 0;
  126.     fParseInProgress = false;
  127.     fWithinElement   = false;
  128.     fNodeStack->removeAllElements();
  129. };
  130. // ---------------------------------------------------------------------------
  131. //  DOMParser: Getter methods
  132. // ---------------------------------------------------------------------------
  133. const XMLValidator& DOMParser::getValidator() const
  134. {
  135.     return *fScanner->getValidator();
  136. }
  137. bool DOMParser::getDoNamespaces() const
  138. {
  139.     return fScanner->getDoNamespaces();
  140. }
  141. bool DOMParser::getExitOnFirstFatalError() const
  142. {
  143.     return fScanner->getExitOnFirstFatal();
  144. }
  145. bool DOMParser::getValidationConstraintFatal() const
  146. {
  147.     return fScanner->getValidationConstraintFatal();
  148. }
  149. DOMParser::ValSchemes DOMParser::getValidationScheme() const
  150. {
  151.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  152.     if (scheme == XMLScanner::Val_Always)
  153.         return Val_Always;
  154.     else if (scheme == XMLScanner::Val_Never)
  155.         return Val_Never;
  156.     return Val_Auto;
  157. }
  158. bool DOMParser::getDoSchema() const
  159. {
  160.     return fScanner->getDoSchema();
  161. }
  162. bool DOMParser::getValidationSchemaFullChecking() const
  163. {
  164.     return fScanner->getValidationSchemaFullChecking();
  165. }
  166. int DOMParser::getErrorCount() const
  167. {
  168.     return fScanner->getErrorCount();
  169. }
  170. XMLCh* DOMParser::getExternalSchemaLocation() const
  171. {
  172.     return fScanner->getExternalSchemaLocation();
  173. }
  174. XMLCh* DOMParser::getExternalNoNamespaceSchemaLocation() const
  175. {
  176.     return fScanner->getExternalNoNamespaceSchemaLocation();
  177. }
  178. // ---------------------------------------------------------------------------
  179. //  DOMParser: Setter methods
  180. // ---------------------------------------------------------------------------
  181. void DOMParser::setDoNamespaces(const bool newState)
  182. {
  183.     fScanner->setDoNamespaces(newState);
  184. }
  185. void DOMParser::setErrorHandler(ErrorHandler* const handler)
  186. {
  187.     fErrorHandler = handler;
  188.     if (fErrorHandler) {
  189.         fScanner->setErrorReporter(this);
  190.         fScanner->setErrorHandler(fErrorHandler);
  191.     }
  192.     else {
  193.         fScanner->setErrorReporter(0);
  194.         fScanner->setErrorHandler(0);
  195.     }
  196. }
  197. void DOMParser::setEntityResolver(EntityResolver* const handler)
  198. {
  199.     fEntityResolver = handler;
  200.     if (fEntityResolver) {
  201.         fScanner->setEntityHandler(this);
  202.         fScanner->setEntityResolver(fEntityResolver);
  203.     }
  204.     else {
  205.         fScanner->setEntityHandler(0);
  206.         fScanner->setEntityResolver(0);
  207.     }
  208. }
  209. void DOMParser::setExitOnFirstFatalError(const bool newState)
  210. {
  211.     fScanner->setExitOnFirstFatal(newState);
  212. }
  213. void DOMParser::setValidationConstraintFatal(const bool newState)
  214. {
  215.     fScanner->setValidationConstraintFatal(newState);
  216. }
  217. void DOMParser::setValidationScheme(const ValSchemes newScheme)
  218. {
  219.     if (newScheme == Val_Never)
  220.         fScanner->setValidationScheme(XMLScanner::Val_Never);
  221.     else if (newScheme == Val_Always)
  222.         fScanner->setValidationScheme(XMLScanner::Val_Always);
  223.     else
  224.         fScanner->setValidationScheme(XMLScanner::Val_Auto);
  225. }
  226. void DOMParser::setDoSchema(const bool newState)
  227. {
  228.     fScanner->setDoSchema(newState);
  229. }
  230. void DOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
  231. {
  232.     fScanner->setValidationSchemaFullChecking(schemaFullChecking);
  233. }
  234. void DOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
  235. {
  236.     fScanner->setExternalSchemaLocation(schemaLocation);
  237. }
  238. void DOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
  239. {
  240.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  241. }
  242. void DOMParser::setExternalSchemaLocation(const char* const schemaLocation)
  243. {
  244.     fScanner->setExternalSchemaLocation(schemaLocation);
  245. }
  246. void DOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
  247. {
  248.     fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
  249. }
  250. // ---------------------------------------------------------------------------
  251. //  DOMParser: Parsing methods
  252. // ---------------------------------------------------------------------------
  253. void DOMParser::parse(const InputSource& source, const bool reuseGrammar)
  254. {
  255.     // Avoid multiple entrance
  256.     if (fParseInProgress)
  257.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  258.     try
  259.     {
  260.         fParseInProgress = true;
  261.         fScanner->scanDocument(source, reuseGrammar);
  262.         fParseInProgress = false;
  263.     }
  264.     catch(...)
  265.     {
  266.         fParseInProgress = false;
  267.         throw;
  268.     }
  269. }
  270. void DOMParser::parse(const XMLCh* const systemId, const bool reuseGrammar)
  271. {
  272.     // Avoid multiple entrance
  273.     if (fParseInProgress)
  274.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  275.     try
  276.     {
  277.         fParseInProgress = true;
  278.         fScanner->scanDocument(systemId, reuseGrammar);
  279.         fParseInProgress = false;
  280.     }
  281.     catch(...)
  282.     {
  283.         fParseInProgress = false;
  284.         throw;
  285.     }
  286. }
  287. void DOMParser::parse(const char* const systemId, const bool reuseGrammar)
  288. {
  289.     // Avoid multiple entrance
  290.     if (fParseInProgress)
  291.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  292.     try
  293.     {
  294.         fParseInProgress = true;
  295.         fScanner->scanDocument(systemId, reuseGrammar);
  296.         fParseInProgress = false;
  297.     }
  298.     catch(...)
  299.     {
  300.         fParseInProgress = false;
  301.         throw;
  302.     }
  303. }
  304. // ---------------------------------------------------------------------------
  305. //  DOMParser: Progressive parse methods
  306. // ---------------------------------------------------------------------------
  307. bool DOMParser::parseFirst( const   XMLCh* const    systemId
  308.                            ,       XMLPScanToken&  toFill
  309.                            , const bool            reuseGrammar)
  310. {
  311.     //
  312.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  313.     //  is in progress.
  314.     //
  315.     if (fParseInProgress)
  316.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  317.     return fScanner->scanFirst(systemId, toFill, reuseGrammar);
  318. }
  319. bool DOMParser::parseFirst( const   char* const         systemId
  320.                            ,       XMLPScanToken&      toFill
  321.                            , const bool                reuseGrammar)
  322. {
  323.     //
  324.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  325.     //  is in progress.
  326.     //
  327.     if (fParseInProgress)
  328.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  329.     return fScanner->scanFirst(systemId, toFill, reuseGrammar);
  330. }
  331. bool DOMParser::parseFirst( const   InputSource&    source
  332.                            ,       XMLPScanToken&  toFill
  333.                            , const bool            reuseGrammar)
  334. {
  335.     //
  336.     //  Avoid multiple entrance. We cannot enter here while a regular parse
  337.     //  is in progress.
  338.     //
  339.     if (fParseInProgress)
  340.         ThrowXML(IOException, XMLExcepts::Gen_ParseInProgress);
  341.     return fScanner->scanFirst(source, toFill, reuseGrammar);
  342. }
  343. bool DOMParser::parseNext(XMLPScanToken& token)
  344. {
  345.     return fScanner->scanNext(token);
  346. }
  347. void DOMParser::parseReset(XMLPScanToken& token)
  348. {
  349.     // Reset the scanner, and then reset the parser
  350.     fScanner->scanReset(token);
  351.     reset();
  352. }
  353. // ---------------------------------------------------------------------------
  354. //  DOMParser: Implementation of the XMLErrorReporter interface
  355. // ---------------------------------------------------------------------------
  356. void DOMParser::error(  const   unsigned int                code
  357.                       , const XMLCh* const                msgDomain
  358.                       , const XMLErrorReporter::ErrTypes  errType
  359.                       , const XMLCh* const                errorText
  360.                       , const XMLCh* const                systemId
  361.                       , const XMLCh* const                publicId
  362.                       , const unsigned int                lineNum
  363.                       , const unsigned int                colNum)
  364. {
  365.     SAXParseException toThrow = SAXParseException
  366.         (
  367.         errorText
  368.         , publicId
  369.         , systemId
  370.         , lineNum
  371.         , colNum
  372.         );
  373.     //
  374.     //  If there is an error handler registered, call it, otherwise ignore
  375.     //  all but the fatal errors.
  376.     //
  377.     if (!fErrorHandler)
  378.     {
  379.         if (errType == XMLErrorReporter::ErrType_Fatal)
  380.             throw toThrow;
  381.         return;
  382.     }
  383.     if (errType == XMLErrorReporter::ErrType_Warning)
  384.         fErrorHandler->warning(toThrow);
  385.     else if (errType >= XMLErrorReporter::ErrType_Fatal)
  386.         fErrorHandler->fatalError(toThrow);
  387.     else
  388.         fErrorHandler->error(toThrow);
  389. }
  390. void DOMParser::resetErrors()
  391. {
  392. }
  393. // ---------------------------------------------------------------------------
  394. //  DOMParser: Implementation of XMLEntityHandler interface
  395. // ---------------------------------------------------------------------------
  396. InputSource*
  397. DOMParser::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId)
  398. {
  399.     //
  400.     //  Just map it to the SAX entity resolver. If there is not one installed,
  401.     //  return a null pointer to cause the default resolution.
  402.     //
  403.     if (fEntityResolver)
  404.         return fEntityResolver->resolveEntity(publicId, systemId);
  405.     return 0;
  406. }
  407. // ---------------------------------------------------------------------------
  408. //  DOMParser: Implementation of XMLDocumentHandler interface
  409. // ---------------------------------------------------------------------------
  410. void DOMParser::docCharacters(  const   XMLCh* const    chars
  411.                               , const unsigned int    length
  412.                               , const bool            cdataSection)
  413. {
  414.     // Ignore chars outside of content
  415.     if (!fWithinElement)
  416.         return;
  417.     if (cdataSection == true)
  418.     {
  419.         DOM_CDATASection node = fDocument.createCDATASection
  420.             (
  421.             DOMString(chars, length)
  422.             );
  423.         fCurrentParent.appendChild(node);
  424.         fCurrentNode = node;
  425.     }
  426.     else
  427.     {
  428.         if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE)
  429.         {
  430.             DOM_Text node = (DOM_Text&)fCurrentNode;
  431.             node.appendData(DOMString(chars, length));
  432.         }
  433.         else
  434.         {
  435.             DOM_Text node = fDocument.createTextNode(DOMString(chars, length));
  436. //If the node type is entityRef then set the readOnly flag to false before appending node
  437. bool oldReadFlag;
  438. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  439. oldReadFlag = fCurrentParent.fImpl->isReadOnly();
  440. fCurrentParent.fImpl->isReadOnly(false);
  441. }
  442.             fCurrentParent.appendChild(node);
  443. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  444. fCurrentParent.fImpl->isReadOnly(oldReadFlag);
  445. }
  446.             fCurrentNode = node;
  447.         }
  448.     }
  449. }
  450. void DOMParser::docComment(const XMLCh* const comment)
  451. {
  452.     DOM_Comment dcom = fDocument.createComment(comment);
  453.     fCurrentParent.appendChild(dcom);
  454.     fCurrentNode = dcom;
  455. }
  456. void DOMParser::docPI(  const   XMLCh* const    target
  457.                       , const XMLCh* const    data)
  458. {
  459.     DOM_ProcessingInstruction pi = fDocument.createProcessingInstruction
  460.         (
  461.         target
  462.         , data
  463.         );
  464.     fCurrentParent.appendChild(pi);
  465.     fCurrentNode = pi;
  466. }
  467. void DOMParser::endEntityReference(const XMLEntityDecl& entDecl)
  468. {
  469.     if (fCreateEntityReferenceNodes == true)
  470.     {
  471.         fCurrentParent = fNodeStack->pop();
  472.         fCurrentNode   = fCurrentParent;
  473.     }
  474. }
  475. void DOMParser::endElement( const   XMLElementDecl&     elemDecl
  476.                            , const unsigned int        urlId
  477.                            , const bool                isRoot)
  478. {
  479.     fCurrentNode   = fCurrentParent;
  480.     fCurrentParent = fNodeStack->pop();
  481.     // If we've hit the end of content, clear the flag
  482.     if (fNodeStack->empty())
  483.         fWithinElement = false;
  484. }
  485. void DOMParser::ignorableWhitespace(const   XMLCh* const    chars
  486.                                     , const unsigned int    length
  487.                                     , const bool            cdataSection)
  488. {
  489.     // Ignore chars before the root element
  490.     if (!fWithinElement || !fIncludeIgnorableWhitespace)
  491.         return;
  492.     if (fCurrentNode.getNodeType() == DOM_Node::TEXT_NODE)
  493.     {
  494.         DOM_Text node = (DOM_Text&)fCurrentNode;
  495.         node.appendData(DOMString(chars, length));
  496.     }
  497.     else
  498.     {
  499.         DOM_Text node = fDocument.createTextNode(DOMString(chars, length));
  500.         TextImpl *text = (TextImpl *) node.fImpl;
  501.         text -> setIgnorableWhitespace(true);
  502. //If the node type is entityRef then set the readOnly flag to false before appending node
  503. bool oldReadFlag;
  504. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  505. oldReadFlag = fCurrentParent.fImpl->isReadOnly();
  506. fCurrentParent.fImpl->isReadOnly(false);
  507. }
  508.         fCurrentParent.appendChild(node);
  509. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  510. fCurrentParent.fImpl->isReadOnly(oldReadFlag);
  511. }
  512.         fCurrentNode = node;
  513.     }
  514. }
  515. void DOMParser::resetDocument()
  516. {
  517.     //
  518.     //  The reset methods are called before a new parse event occurs.
  519.     //  Reset this parsers state to clear out anything that may be left
  520.     //  from a previous use, in particular the DOM document itself.
  521.     //
  522.     this->reset();
  523. }
  524. void DOMParser::startDocument()
  525. {
  526.     // Just set the document as the current parent and current node
  527.     fCurrentParent = fDocument;
  528.     fCurrentNode   = fDocument;
  529.     // set DOM error checking off
  530.     fDocument.setErrorChecking(false);
  531. }
  532. void DOMParser::endDocument()
  533. {
  534.     // set DOM error checking back on
  535.     fDocument.setErrorChecking(true);
  536. }
  537. void DOMParser::startElement(const  XMLElementDecl&         elemDecl
  538.                              , const unsigned int            urlId
  539.                              , const XMLCh* const            elemPrefix
  540.                              , const RefVectorOf<XMLAttr>&   attrList
  541.                              , const unsigned int            attrCount
  542.                              , const bool                    isEmpty
  543.                              , const bool                    isRoot)
  544. {
  545.     DOM_Element     elem;
  546.     DocumentImpl    *docImpl = (DocumentImpl *)fDocument.fImpl;
  547.     if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on
  548.         XMLBuffer buf;
  549.         DOMString namespaceURI = 0;
  550.         if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  551.             fScanner->getURIText(urlId, buf);   //get namespaceURI
  552.             namespaceURI = DOMString(buf.getRawBuffer());
  553.         }
  554.         elem = fDocument.createElementNS(namespaceURI, elemDecl.getFullName());
  555.         ElementImpl *elemImpl = (ElementImpl *) elem.fImpl;
  556.         for (unsigned int index = 0; index < attrCount; ++index) {
  557.             static const XMLCh XMLNS[] = {
  558.             chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull
  559.             };
  560.             const XMLAttr* oneAttrib = attrList.elementAt(index);
  561.             unsigned int attrURIId = oneAttrib -> getURIId();
  562.             namespaceURI = 0;
  563.             if (!XMLString::compareString(oneAttrib -> getName(), XMLNS))    //for xmlns=...
  564.                 attrURIId = fScanner->getXMLNSNamespaceId();
  565.             if (attrURIId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
  566.                 fScanner->getURIText(attrURIId, buf);   //get namespaceURI
  567.                 namespaceURI = DOMString(buf.getRawBuffer());
  568.             }
  569.             AttrImpl *attr = elemImpl->setAttributeNS(namespaceURI, oneAttrib -> getQName(),
  570.             oneAttrib -> getValue());
  571.             // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  572.             //   that is constructed for use by GetElementByID().
  573.             //
  574.             if (oneAttrib->getType()==XMLAttDef::ID)
  575.             {
  576.                 if (docImpl->fNodeIDMap == 0)
  577.                     docImpl->fNodeIDMap = new NodeIDMap(500);
  578.                 docImpl->fNodeIDMap->add(attr);
  579.                 attr->isIdAttr(true);
  580.             }
  581.             attr->setSpecified(oneAttrib->getSpecified());
  582.         }
  583.     }
  584. else {    //DOM Level 1
  585. elem = fDocument.createElement(elemDecl.getFullName());
  586. ElementImpl *elemImpl = (ElementImpl *) elem.fImpl;
  587. for (unsigned int index = 0; index < attrCount; ++index) {
  588. const XMLAttr* oneAttrib = attrList.elementAt(index);
  589. AttrImpl *attr = elemImpl->setAttribute(oneAttrib->getName(), oneAttrib->getValue());
  590. attr->setSpecified(oneAttrib->getSpecified());
  591. // Attributes of type ID.  If this is one, add it to the hashtable of IDs
  592. //   that is constructed for use by GetElementByID().
  593. //
  594. if (oneAttrib->getType()==XMLAttDef::ID)
  595. {
  596. if (docImpl->fNodeIDMap == 0)
  597. docImpl->fNodeIDMap = new NodeIDMap(500);
  598. docImpl->fNodeIDMap->add(attr);
  599. attr->isIdAttr(true);
  600. }
  601. }
  602.     }
  603.     //If the node type is entityRef then set the readOnly flag to false before appending node
  604. bool oldReadFlag;
  605. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  606. oldReadFlag = fCurrentParent.fImpl->isReadOnly();
  607. fCurrentParent.fImpl->isReadOnly(false);
  608. }
  609.     fCurrentParent.appendChild(elem);
  610. if (fCurrentParent.getNodeType() == DOM_Node::ENTITY_REFERENCE_NODE) {
  611. fCurrentParent.fImpl->isReadOnly(oldReadFlag);
  612. }
  613.     fNodeStack->push(fCurrentParent);
  614.     fCurrentParent = elem;
  615.     fCurrentNode = elem;
  616.     fWithinElement = true;
  617.     // If an empty element, do end right now (no endElement() will be called)
  618.     if (isEmpty)
  619.         endElement(elemDecl, urlId, isRoot);
  620. }
  621. void DOMParser::startEntityReference(const XMLEntityDecl& entDecl)
  622. {
  623.     if (fCreateEntityReferenceNodes == true)
  624.     {
  625. DOMString entName(entDecl.getName());
  626.         DOM_EntityReference er = fDocument.createEntityReference(entName);
  627.         fCurrentParent.appendChild(er);
  628.         fNodeStack->push(fCurrentParent);
  629.         fCurrentParent = er;
  630.         fCurrentNode = er;
  631. // this entityRef needs to be stored in Entity map too.
  632.         // We'd decide later whether the entity nodes should be created by a
  633.         // separated method in parser or not. For now just stick it in if
  634.         // the ref nodes are created
  635. EntityImpl* entity = (EntityImpl*)fDocumentType->entities->getNamedItem(entName);
  636. entity->setEntityRef((EntityReferenceImpl*)er.fImpl);
  637.     }
  638. }
  639. void DOMParser::XMLDecl(const   XMLCh* const version
  640.                         , const XMLCh* const encoding
  641.                         , const XMLCh* const standalone
  642.                         , const XMLCh* const actualEncStr)
  643. {
  644.     //This is a non-standard extension to creating XMLDecl type nodes and attching to DOM Tree
  645.     // currently this flag it set to false unless user explicitly asks for it
  646.     // Needs to be revisited after W3C specs are laid out on this issue.
  647.     if (fToCreateXMLDeclTypeNode) {
  648.         DOMString ver(version);
  649.         DOMString enc(encoding);
  650.         DOMString isStd(standalone);
  651.         DOM_XMLDecl xmlDecl = fDocument.createXMLDecl(ver, enc, isStd);
  652.         fCurrentParent.appendChild(xmlDecl);
  653.     }
  654. }
  655. // ---------------------------------------------------------------------------
  656. //  DOMParser: Deprecated methods
  657. // ---------------------------------------------------------------------------
  658. bool DOMParser::getDoValidation() const
  659. {
  660.     //
  661.     //  We don't want to tie the public parser classes to the enum used
  662.     //  by the scanner, so we use a separate one and map.
  663.     //
  664.     //  DON'T mix the new and old methods!!
  665.     //
  666.     const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
  667.     if (scheme == XMLScanner::Val_Always)
  668.         return true;
  669.     return false;
  670. }
  671. void DOMParser::setDoValidation(const bool newState)
  672. {
  673.     fScanner->setDoValidation
  674.     (
  675.         newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
  676.     );
  677. }
  678. //doctypehandler interfaces
  679. void DOMParser::attDef
  680. (
  681.     const   DTDElementDecl&     elemDecl
  682.     , const DTDAttDef&          attDef
  683.     , const bool                ignoring
  684. )
  685. {
  686.     if (fDocumentType->isIntSubsetReading())
  687.     {
  688.         DOMString attString;
  689.         if (elemDecl.hasAttDefs())
  690.         {
  691.             attString.appendData(chOpenAngle);
  692.             attString.appendData(chBang);
  693.             attString.appendData(XMLUni::fgAttListString);
  694.             attString.appendData(chSpace);
  695.             attString.appendData(elemDecl.getFullName());
  696.             attString.appendData(chSpace);
  697.             attString.appendData(attDef.getFullName());
  698.             // Get the type and display it
  699.             const XMLAttDef::AttTypes type = attDef.getType();
  700.             switch(type)
  701.             {
  702.             case XMLAttDef::CData :
  703.                 attString.appendData(chSpace);
  704.                 attString.appendData(XMLUni::fgCDATAString);
  705.                 break;
  706.             case XMLAttDef::ID :
  707.                 attString.appendData(chSpace);
  708.                 attString.appendData(XMLUni::fgIDString);
  709.                 break;
  710.             case XMLAttDef::IDRef :
  711.                 attString.appendData(chSpace);
  712.                 attString.appendData(XMLUni::fgIDRefString);
  713.                 break;
  714.             case XMLAttDef::IDRefs :
  715.                 attString.appendData(chSpace);
  716.                 attString.appendData(XMLUni::fgIDRefsString);
  717.                 break;
  718.             case XMLAttDef::Entity :
  719.                 attString.appendData(chSpace);
  720.                 attString.appendData(XMLUni::fgEntityString);
  721.                 break;
  722.             case XMLAttDef::Entities :
  723.                 attString.appendData(chSpace);
  724.                 attString.appendData(XMLUni::fgEntitiesString);
  725.                 break;
  726.             case XMLAttDef::NmToken :
  727.                 attString.appendData(chSpace);
  728.                 attString.appendData(XMLUni::fgNmTokenString);
  729.                 break;
  730.             case XMLAttDef::NmTokens :
  731.                 attString.appendData(chSpace);
  732.                 attString.appendData(XMLUni::fgNmTokensString);
  733.                 break;
  734.             case XMLAttDef::Notation :
  735.                 attString.appendData(chSpace);
  736.                 attString.appendData(XMLUni::fgNotationString);
  737.                 break;
  738.             case XMLAttDef::Enumeration :
  739.                 attString.appendData(chSpace);
  740.                 //  attString.appendData(XMLUni::fgEnumerationString);
  741.                 const XMLCh* enumString = attDef.getEnumeration();
  742.                 int length = XMLString::stringLen(enumString);
  743.                 if (length > 0) {
  744.                     DOMString anotherEnumString;
  745.                     anotherEnumString.appendData(chOpenParen );
  746.                     for(int i=0; i<length; i++) {
  747.                         if (enumString[i] == chSpace)
  748.                             anotherEnumString.appendData(chPipe);
  749.                         else
  750.                             anotherEnumString.appendData(enumString[i]);
  751.                     }
  752.                     anotherEnumString.appendData(chCloseParen);
  753.                     attString.appendData(anotherEnumString);
  754.                 }
  755.                 break;
  756.             }
  757.             //get te default types of the attlist
  758.             const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
  759.             switch(def)
  760.             {
  761.             case XMLAttDef::Required :
  762.                 attString.appendData(chSpace);
  763.                 attString.appendData(XMLUni::fgRequiredString);
  764.                 break;
  765.             case XMLAttDef::Implied :
  766.                 attString.appendData(chSpace);
  767.                 attString.appendData(XMLUni::fgImpliedString);
  768.                 break;
  769.             case XMLAttDef::Fixed :
  770.                 attString.appendData(chSpace);
  771.                 attString.appendData(XMLUni::fgFixedString);
  772.                 break;
  773.             }
  774.             const XMLCh* defaultValue = attDef.getValue();
  775.             if (defaultValue != 0) {
  776.                 attString.appendData(chSpace);
  777.                 attString.appendData(chDoubleQuote);
  778.                 attString.appendData(defaultValue);
  779.                 attString.appendData(chDoubleQuote);
  780.             }
  781.             attString.appendData(chCloseAngle);
  782.             fDocumentType->internalSubset.appendData(attString);
  783.         }
  784.     }
  785. }
  786. void DOMParser::doctypeComment
  787. (
  788.     const   XMLCh* const    comment
  789. )
  790. {
  791.     if (fDocumentType->isIntSubsetReading())
  792.     {
  793.         if (comment != 0)
  794.         {
  795.             DOMString comString;
  796.             comString.appendData(XMLUni::fgCommentString);
  797.             comString.appendData(chSpace);
  798.             comString.appendData(comment);
  799.             comString.appendData(chSpace);
  800.             comString.appendData(chDash);
  801.             comString.appendData(chDash);
  802.             comString.appendData(chCloseAngle);
  803.             fDocumentType->internalSubset.appendData(comString);
  804.         }
  805.     }
  806. }
  807. void DOMParser::doctypeDecl
  808. (
  809.     const   DTDElementDecl& elemDecl
  810.     , const XMLCh* const    publicId
  811.     , const XMLCh* const    systemId
  812.     , const bool            hasIntSubset
  813. )
  814. {
  815. DOM_DocumentType dt;
  816. dt = fDocument.getImplementation().createDocumentType(elemDecl.getFullName(), publicId, systemId);
  817.     fDocumentType = (DocumentTypeImpl*)dt.fImpl;
  818. ((DocumentImpl*)fDocument.fImpl)->setDocumentType(fDocumentType);
  819. }
  820. void DOMParser::doctypePI
  821. (
  822.     const   XMLCh* const    target
  823.     , const XMLCh* const    data
  824. )
  825. {
  826.     if (fDocumentType->isIntSubsetReading())
  827. {
  828. //add these chars to internalSubset variable
  829.         DOMString pi;
  830.         pi.appendData(chOpenAngle);
  831.         pi.appendData(chQuestion);
  832.         pi.appendData(target);
  833.         pi.appendData(chSpace);
  834.         pi.appendData(data);
  835.         pi.appendData(chQuestion);
  836.         pi.appendData(chCloseAngle);
  837. fDocumentType->internalSubset.appendData(pi);
  838. }
  839. }
  840. void DOMParser::doctypeWhitespace
  841. (
  842.     const   XMLCh* const    chars
  843.     , const unsigned int    length
  844. )
  845. {
  846.     if (fDocumentType->isIntSubsetReading())
  847. fDocumentType->internalSubset.appendData(chars);
  848. }
  849. void DOMParser::elementDecl
  850. (
  851.     const   DTDElementDecl& decl
  852.     , const bool            isIgnored
  853. )
  854. {
  855.     if (fDocumentType->isIntSubsetReading())
  856. {
  857.         DOMString elemDecl;
  858.         elemDecl.appendData(chOpenAngle);
  859.         elemDecl.appendData(chBang);
  860.         elemDecl.appendData(XMLUni::fgElemString);
  861.         elemDecl.appendData(chSpace);
  862.         elemDecl.appendData(decl.getFullName());
  863.         //get the ContentSpec information
  864.         const XMLCh* contentModel = decl.getFormattedContentModel();
  865.         if (contentModel != 0) {
  866.             elemDecl.appendData(chSpace);
  867.             elemDecl.appendData(contentModel);
  868.         }
  869.         elemDecl.appendData(chCloseAngle);
  870. fDocumentType->internalSubset.appendData(elemDecl);
  871. }
  872. }
  873. void DOMParser::endAttList
  874. (
  875.     const   DTDElementDecl& elemDecl
  876. )
  877. {
  878. // this section sets up default attributes.
  879. // default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
  880. // default attribute data attached to the document is used to conform to the
  881. // DOM spec regarding creating element nodes & removing attributes with default values
  882. // see DocumentTypeImpl
  883. if (elemDecl.hasAttDefs())
  884. {
  885. XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
  886. XMLAttDef* attr = 0;
  887. AttrImpl* insertAttr = 0;
  888. DOM_Element dom_elem = fDocument.createElement(elemDecl.getFullName());
  889. ElementImpl* elem = (ElementImpl*)(dom_elem.fImpl);
  890. while (defAttrs->hasMoreElements())
  891.         {
  892.             attr = &defAttrs->nextElement();
  893.             if (attr->getValue() != null)
  894.             {
  895.                 if (fScanner->getDoNamespaces())
  896.                 {
  897.                     // DOM Level 2 wants all namespace declaration attributes
  898.                     // to be bound to "http://www.w3.org/2000/xmlns/"
  899.                     // So as long as the XML parser doesn't do it, it needs to
  900.                     // done here.
  901.                     DOMString qualifiedName = attr->getFullName();
  902.                     int index = DocumentImpl::indexofQualifiedName(qualifiedName);
  903.                     XMLBuffer buf;
  904.                     static const XMLCh XMLNS[] = {
  905.                         chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};
  906.                     if (index > 0) {
  907.                         // there is prefix
  908.                         // map to XML URI for all cases except when prefix == "xmlns"
  909.                         DOMString prefix = qualifiedName.substringData(0, index);
  910.                         if (prefix.equals(XMLNS))
  911.                             buf.append(XMLUni::fgXMLNSURIName);
  912.                         else
  913.                             buf.append(XMLUni::fgXMLURIName);
  914.                     }
  915.                     else {
  916.                         //   No prefix
  917.                         if (qualifiedName.equals(XMLNS))
  918.                             buf.append(XMLUni::fgXMLNSURIName);
  919.                     }
  920.                     insertAttr = new AttrNSImpl((DocumentImpl*)fDocument.fImpl,
  921.                        DOMString(buf.getRawBuffer()),     // NameSpaceURI
  922.                        qualifiedName);   // qualified name
  923.                 }
  924.                 else
  925.                 {
  926.                     // Namespaces is turned off...
  927.                     insertAttr = new AttrImpl((DocumentImpl*)fDocument.fImpl, attr->getFullName());
  928.                 }
  929.                 insertAttr->setValue(attr->getValue());
  930.                 elem->setAttributeNode(insertAttr);
  931.                 insertAttr->setSpecified(false);
  932.             }
  933.         }
  934.         ElementImpl *previousElem = (ElementImpl *)
  935.                 fDocumentType->getElements()->setNamedItem( elem );
  936.         //
  937.         //  If this new element is replacing an element node that was already
  938.         //    in the element named node map, we need to delete the original
  939.         //    element node, assuming no-one else was referencing it.
  940.         //
  941.         if (previousElem != 0 && previousElem->nodeRefCount == 0)
  942.             NodeImpl::deleteIf(previousElem);
  943.     }
  944. }
  945. void DOMParser::endIntSubset()
  946. {
  947. fDocumentType->intSubsetReading = false;
  948. }
  949. void DOMParser::endExtSubset()
  950. {
  951. }
  952. void DOMParser::entityDecl
  953. (
  954.     const   DTDEntityDecl&  entityDecl
  955.     , const bool            isPEDecl
  956.     , const bool            isIgnored
  957. )
  958. {
  959. EntityImpl* entity = ((DocumentImpl*)fDocument.fImpl)->createEntity(entityDecl.getName());
  960. entity->setPublicId(entityDecl.getPublicId());
  961. entity->setSystemId(entityDecl.getSystemId());
  962. entity->setNotationName(entityDecl.getNotationName());
  963.     EntityImpl *previousDef = (EntityImpl *)
  964.     fDocumentType->entities->setNamedItem( entity );
  965.     //
  966.     //  If this new entity node is replacing an entity node that was already
  967.     //    in the entities named node map (happens if documents redefine the
  968.     //    predefined entited such as lt), we need to delete the original
  969.     //    entitiy node, assuming no-one else was referencing it.
  970.     //
  971.     if (previousDef != 0 && previousDef->nodeRefCount == 0)
  972.              NodeImpl::deleteIf(previousDef);
  973. if (fDocumentType->isIntSubsetReading())
  974. {
  975. //add thes chars to internalSubset variable
  976. DOMString entityName;
  977. entityName.appendData(chOpenAngle);
  978.         entityName.appendData(chBang);
  979. entityName.appendData(XMLUni::fgEntityString);
  980.         entityName.appendData(chSpace);
  981.         entityName.appendData(entityDecl.getName());
  982.         DOMString id = entity->getPublicId();
  983.         if (id != 0) {
  984.             entityName.appendData(chSpace);
  985.             entityName.appendData(XMLUni::fgPubIDString);
  986.             entityName.appendData(chSpace);
  987.             entityName.appendData(chDoubleQuote);
  988.             entityName.appendData(id);
  989.             entityName.appendData(chDoubleQuote);
  990.         }
  991.         id = entity->getSystemId();
  992.         if (id != 0) {
  993.             entityName.appendData(chSpace);
  994.             entityName.appendData(XMLUni::fgSysIDString);
  995.             entityName.appendData(chSpace);
  996.             entityName.appendData(chDoubleQuote);
  997.             entityName.appendData(id);
  998.             entityName.appendData(chDoubleQuote);
  999.         }
  1000.         id = entity->getNotationName();
  1001.         if (id != 0) {
  1002.             entityName.appendData(chSpace);
  1003.             entityName.appendData(XMLUni::fgNDATAString);
  1004.             entityName.appendData(chSpace);
  1005.             entityName.appendData(chDoubleQuote);
  1006.             entityName.appendData(id);
  1007.             entityName.appendData(chDoubleQuote);
  1008.         }
  1009.         id = entityDecl.getValue();
  1010.         if (id !=0) {
  1011.             entityName.appendData(chSpace);
  1012.             entityName.appendData(chDoubleQuote);
  1013.             entityName.appendData(id);
  1014.             entityName.appendData(chDoubleQuote);
  1015.         }
  1016.         entityName.appendData(chCloseAngle);
  1017.         fDocumentType->internalSubset.appendData(entityName);
  1018.     }
  1019. }
  1020. void DOMParser::resetDocType()
  1021. {
  1022. fDocumentType = null;
  1023. }
  1024. void DOMParser::notationDecl
  1025. (
  1026.     const   XMLNotationDecl&    notDecl
  1027.     , const bool                isIgnored
  1028. )
  1029. {
  1030. NotationImpl* notation = ((DocumentImpl*)fDocument.fImpl)->createNotation(notDecl.getName());
  1031. notation->setPublicId(notDecl.getPublicId());
  1032. notation->setSystemId(notDecl.getSystemId());
  1033.     NotationImpl *previousNot = (NotationImpl *)
  1034.        fDocumentType->notations->setNamedItem( notation );
  1035.     //
  1036.     //  If this new notation is replacing a notation node that was already
  1037.     //    in the notation named node map, we need to delete the original
  1038.     //    notation node, assuming no-one else was referencing it.
  1039.     //
  1040.     if (previousNot != 0 && previousNot->nodeRefCount == 0)
  1041.         NodeImpl::deleteIf(previousNot);
  1042. }
  1043. void DOMParser::startAttList
  1044. (
  1045.     const   DTDElementDecl& elemDecl
  1046. )
  1047. {
  1048. }
  1049. void DOMParser::startIntSubset()
  1050. {
  1051. fDocumentType->intSubsetReading = true;
  1052. }
  1053. void DOMParser::startExtSubset()
  1054. {
  1055. }
  1056. void DOMParser::TextDecl
  1057. (
  1058.     const   XMLCh* const    versionStr
  1059.     , const XMLCh* const    encodingStr
  1060. )
  1061. {
  1062. }