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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001-2002 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.  * $Id: DOMDocumentTypeImpl.cpp,v 1.22 2003/05/22 19:35:04 peiyongz Exp $
  58.  */
  59. #include "DOMDocumentTypeImpl.hpp"
  60. #include <xercesc/dom/DOMNode.hpp>
  61. #include <xercesc/dom/DOMException.hpp>
  62. #include <xercesc/dom/DOMImplementationRegistry.hpp>
  63. #include <xercesc/dom/DOMImplementation.hpp>
  64. #include <xercesc/util/XMLUniDefs.hpp>
  65. #include <xercesc/util/XMLChar.hpp>
  66. #include <xercesc/util/XMLRegisterCleanup.hpp>
  67. #include "DOMNamedNodeMapImpl.hpp"
  68. #include "DOMDocumentImpl.hpp"
  69. #include "DOMCasts.hpp"
  70. XERCES_CPP_NAMESPACE_BEGIN
  71. // ---------------------------------------------------------------------------
  72. //  Local static data
  73. // ---------------------------------------------------------------------------
  74. static DOMDocument*       sDocument = 0;
  75. static XMLRegisterCleanup documentCleanup;
  76. static void reinitDocument()
  77. {
  78.     if (sDocument) {
  79.         sDocument->release();
  80.         sDocument = 0;
  81.     }
  82. }
  83. static DOMDocument& gDocTypeDocument()
  84. {
  85.     if (!sDocument)
  86.     {
  87.         static const XMLCh gCoreStr[] = { chLatin_C, chLatin_o, chLatin_r, chLatin_e, chNull };
  88.         DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(gCoreStr);
  89.         DOMDocument* tmpDoc = impl->createDocument();                   // document type object (DTD).
  90.         if (XMLPlatformUtils::compareAndSwap((void**)&sDocument, tmpDoc, 0))
  91.         {
  92.             // Someone beat us to it, so let's clean up ours
  93.             delete tmpDoc;
  94.         }
  95.         else
  96.         {
  97.             documentCleanup.registerCleanup(reinitDocument);
  98.         }
  99.     }
  100.     return *sDocument;
  101. }
  102. DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
  103.                                    const XMLCh *dtName,
  104.                                    bool heap)
  105.     : fNode(ownerDoc),
  106.     fParent(ownerDoc),
  107.     fPublicId(0),
  108.     fSystemId(0),
  109.     fName(0),
  110.     fIntSubsetReading(false),
  111.     fEntities(0),
  112.     fNotations(0),
  113.     fElements(0),
  114.     fInternalSubset(0),
  115.     fIsCreatedFromHeap(heap)
  116. {
  117.     if (ownerDoc) {
  118.         fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(dtName);
  119.         fEntities = new (ownerDoc) DOMNamedNodeMapImpl(this);
  120.         fNotations= new (ownerDoc) DOMNamedNodeMapImpl(this);
  121.         fElements = new (ownerDoc) DOMNamedNodeMapImpl(this);
  122.     }
  123.     else {
  124.         DOMDocument* doc = &gDocTypeDocument();
  125.         fName = ((DOMDocumentImpl *)doc)->getPooledString(dtName);
  126.         fEntities = new (doc) DOMNamedNodeMapImpl(this);
  127.         fNotations= new (doc) DOMNamedNodeMapImpl(this);
  128.         fElements = new (doc) DOMNamedNodeMapImpl(this);
  129.     }
  130. };
  131. //Introduced in DOM Level 2
  132. DOMDocumentTypeImpl::DOMDocumentTypeImpl(DOMDocument *ownerDoc,
  133.                                    const XMLCh *qualifiedName,
  134.                                    const XMLCh *pubId,
  135.                                    const XMLCh *sysId,
  136.                                    bool heap)
  137.     : fNode(ownerDoc),
  138.     fParent(ownerDoc),
  139.     fPublicId(0),
  140.     fSystemId(0),
  141.     fName(0),
  142.     fIntSubsetReading(false),
  143.     fEntities(0),
  144.     fNotations(0),
  145.     fElements(0),
  146.     fInternalSubset(0),
  147.     fIsCreatedFromHeap(heap)
  148. {
  149.     int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);
  150.     if (index < 0)
  151.         throw DOMException(DOMException::NAMESPACE_ERR, 0);
  152.     else if (index > 0)
  153.     {
  154.         // we have to make sure the qualifiedName has correct prefix and localName
  155.         // although we don't really to store them separately
  156.         XMLCh* newName;
  157.         XMLCh temp[4000];
  158.         if (index >= 3999)
  159.             newName = (XMLCh*) XMLPlatformUtils::fgMemoryManager->allocate
  160.             (
  161.                 (XMLString::stringLen(qualifiedName)+1) * sizeof(XMLCh)
  162.             );//new XMLCh[XMLString::stringLen(qualifiedName)+1];
  163.         else
  164.             newName = temp;
  165.         XMLString::copyNString(newName, qualifiedName, index);
  166.         newName[index] = chNull;
  167.         // Before we carry on, we should check if the prefix or localName are valid XMLName
  168.         if (ownerDoc) {
  169.             if (!((DOMDocumentImpl*)ownerDoc)->isXMLName(newName) || !((DOMDocumentImpl*)ownerDoc)->isXMLName(qualifiedName+index+1))
  170.                 throw DOMException(DOMException::NAMESPACE_ERR, 0);
  171.         }
  172.         else {
  173.             // document is not there yet, so assume XML 1.0
  174.             if (!XMLChar1_0::isValidName(newName, index) || !XMLChar1_0::isValidName(qualifiedName+index+1, XMLString::stringLen(qualifiedName)-index-1))
  175.                 throw DOMException(DOMException::NAMESPACE_ERR, 0);
  176.         }
  177.         if (index >= 3999)
  178.             XMLPlatformUtils::fgMemoryManager->deallocate(newName);//delete[] newName;
  179.     }
  180.     if (ownerDoc) {
  181.         DOMDocumentImpl *docImpl = (DOMDocumentImpl *)ownerDoc;
  182.         fPublicId = docImpl->cloneString(pubId);
  183.         fSystemId = docImpl->cloneString(sysId);
  184.         fName = ((DOMDocumentImpl *)ownerDoc)->getPooledString(qualifiedName);
  185.         fEntities = new (ownerDoc) DOMNamedNodeMapImpl(this);
  186.         fNotations= new (ownerDoc) DOMNamedNodeMapImpl(this);
  187.         fElements = new (ownerDoc) DOMNamedNodeMapImpl(this);
  188.     }
  189.     else {
  190.         DOMDocument* doc = &gDocTypeDocument();
  191.         fPublicId = ((DOMDocumentImpl*) doc)->cloneString(pubId);
  192.         fSystemId = ((DOMDocumentImpl*) doc)->cloneString(sysId);
  193.         fName = ((DOMDocumentImpl*) doc)->getPooledString(qualifiedName);
  194.         fEntities = new (doc) DOMNamedNodeMapImpl(this);
  195.         fNotations= new (doc) DOMNamedNodeMapImpl(this);
  196.         fElements = new (doc) DOMNamedNodeMapImpl(this);
  197.     }
  198. };
  199. DOMDocumentTypeImpl::DOMDocumentTypeImpl(const DOMDocumentTypeImpl &other, bool heap, bool deep)
  200.     : fNode(other.fNode),
  201.     fParent(other.fParent),
  202.     fChild(other.fChild),
  203.     fPublicId(0),
  204.     fSystemId(0),
  205.     fName(0),
  206.     fIntSubsetReading(other.fIntSubsetReading),
  207.     fEntities(0),
  208.     fNotations(0),
  209.     fElements(0),
  210.     fInternalSubset(0),
  211.     fIsCreatedFromHeap(heap)
  212. {
  213.     fName = other.fName;
  214.     //DOM Level 2
  215.     fPublicId        = other.fPublicId;
  216.     fSystemId        = other.fSystemId;
  217.     fInternalSubset  = other.fInternalSubset;
  218.     if ((DOMDocumentImpl *)this->fNode.getOwnerDocument() && deep)
  219.         fParent.cloneChildren(&other);
  220.     fEntities = ((DOMNamedNodeMapImpl *)other.fEntities)->cloneMap(this);
  221.     fNotations= ((DOMNamedNodeMapImpl *)other.fNotations)->cloneMap(this);
  222.     fElements = ((DOMNamedNodeMapImpl *)other.fElements)->cloneMap(this);
  223. }
  224. DOMDocumentTypeImpl::~DOMDocumentTypeImpl()
  225. {
  226. }
  227. DOMNode *DOMDocumentTypeImpl::cloneNode(bool deep) const
  228. {
  229.     DOMNode* newNode = 0;
  230.     if (castToNodeImpl(this)->getOwnerDocument())
  231.         newNode = new (castToNodeImpl(this)->getOwnerDocument(), DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(*this, false, deep);
  232.     else
  233.         newNode = new (&gDocTypeDocument(), DOMDocumentImpl::DOCUMENT_TYPE_OBJECT) DOMDocumentTypeImpl(*this, false, deep);
  234.     fNode.callUserDataHandlers(DOMUserDataHandler::NODE_CLONED, this, newNode);
  235.     return newNode;
  236. }
  237. /**
  238.  * NON-DOM
  239.  * set the ownerDocument of this node and its children
  240.  */
  241. void DOMDocumentTypeImpl::setOwnerDocument(DOMDocument *doc) {
  242.     if (castToNodeImpl(this)->getOwnerDocument()) {
  243.         fNode.setOwnerDocument(doc);
  244.         fParent.setOwnerDocument(doc);
  245.     }
  246.     else {
  247.         if (doc) {
  248.             DOMDocumentImpl *docImpl = (DOMDocumentImpl *)doc;
  249.             fPublicId = docImpl->cloneString(fPublicId);
  250.             fSystemId = docImpl->cloneString(fSystemId);
  251.             fInternalSubset = docImpl->cloneString(fInternalSubset);
  252.             fName = docImpl->getPooledString(fName);
  253.             
  254.             fNode.setOwnerDocument(doc);
  255.             fParent.setOwnerDocument(doc);
  256.             DOMNamedNodeMap* entitiesTemp = ((DOMNamedNodeMapImpl *)fEntities)->cloneMap(this);
  257.             DOMNamedNodeMap* notationsTemp = ((DOMNamedNodeMapImpl *)fNotations)->cloneMap(this);
  258.             DOMNamedNodeMap* elementsTemp = ((DOMNamedNodeMapImpl *)fElements)->cloneMap(this);
  259.             fEntities = entitiesTemp;
  260.             fNotations = notationsTemp;
  261.             fElements = elementsTemp;
  262.         }
  263.     }
  264. }
  265. const XMLCh * DOMDocumentTypeImpl::getNodeName() const
  266. {
  267.     return fName;
  268. };
  269. short DOMDocumentTypeImpl::getNodeType()  const {
  270.     return DOMNode::DOCUMENT_TYPE_NODE;
  271. };
  272. DOMNamedNodeMap *DOMDocumentTypeImpl::getEntities() const
  273. {
  274.     return fEntities;
  275. };
  276. const XMLCh * DOMDocumentTypeImpl::getName() const
  277. {
  278.     return fName;
  279. };
  280. DOMNamedNodeMap *DOMDocumentTypeImpl::getNotations() const
  281. {
  282.     return fNotations;
  283. };
  284. DOMNamedNodeMap *DOMDocumentTypeImpl::getElements() const
  285. {
  286.     return fElements;
  287. };
  288. void DOMDocumentTypeImpl::setNodeValue(const XMLCh *val)
  289. {
  290.     fNode.setNodeValue(val);
  291. };
  292. void DOMDocumentTypeImpl::setReadOnly(bool readOnl, bool deep)
  293. {
  294.     fNode.setReadOnly(readOnl,deep);
  295.     if (fEntities)
  296.         ((DOMNamedNodeMapImpl *)fEntities)->setReadOnly(readOnl,true);
  297.     if (fNotations)
  298.         ((DOMNamedNodeMapImpl *)fNotations)->setReadOnly(readOnl,true);
  299. };
  300. //Introduced in DOM Level 2
  301. const XMLCh * DOMDocumentTypeImpl::getPublicId() const
  302. {
  303.     return fPublicId;
  304. }
  305. const XMLCh * DOMDocumentTypeImpl::getSystemId() const
  306. {
  307.     return fSystemId;
  308. }
  309. const XMLCh * DOMDocumentTypeImpl::getInternalSubset() const
  310. {
  311.     return fInternalSubset;
  312. }
  313. bool DOMDocumentTypeImpl::isIntSubsetReading() const
  314. {
  315.     return fIntSubsetReading;
  316. }
  317. //set functions
  318. void DOMDocumentTypeImpl::setPublicId(const XMLCh *value)
  319. {
  320.     // revist.  Why shouldn't 0 be assigned like any other value?
  321.     if (value == 0)
  322.         return;
  323.     if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
  324.         fPublicId = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
  325.     else {
  326.         fPublicId = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
  327.     }
  328. }
  329. void DOMDocumentTypeImpl::setSystemId(const XMLCh *value)
  330. {
  331.     if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
  332.         fSystemId = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
  333.     else {
  334.         fSystemId = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
  335.     }
  336. }
  337. void DOMDocumentTypeImpl::setInternalSubset(const XMLCh *value)
  338. {
  339.     if ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())
  340.         fInternalSubset = ((DOMDocumentImpl *)castToNodeImpl(this)->getOwnerDocument())->cloneString(value);
  341.     else {
  342.         fInternalSubset = ((DOMDocumentImpl *)&gDocTypeDocument())->cloneString(value);
  343.     }
  344. }
  345. void DOMDocumentTypeImpl::release()
  346. {
  347.     if (fNode.isOwned()) {
  348.         if (fNode.isToBeReleased()) {
  349.             // we are calling from documnet.release() which will notify the user data handler
  350.             if (fIsCreatedFromHeap) {
  351.                 DOMDocumentType* docType = this;
  352.                 delete docType;
  353.             }
  354.         }
  355.         else
  356.             throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
  357.     }
  358.     else {
  359.         if (fIsCreatedFromHeap) {
  360.             fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
  361.             DOMDocumentType* docType = this;
  362.             delete docType;
  363.         }
  364.         else {
  365.             DOMDocumentImpl* doc = (DOMDocumentImpl*) getOwnerDocument();
  366.             if (doc) {
  367.                 fNode.callUserDataHandlers(DOMUserDataHandler::NODE_DELETED, 0, 0);
  368.                 doc->release(this, DOMDocumentImpl::DOCUMENT_TYPE_OBJECT);
  369.             }
  370.             else {
  371.                 // shouldn't reach here
  372.                 throw DOMException(DOMException::INVALID_ACCESS_ERR,0);
  373.             }
  374.         }
  375.     }
  376. }
  377. //
  378. // Delegation for functions inherited from Node
  379. //
  380.            DOMNode*         DOMDocumentTypeImpl::appendChild(DOMNode *newChild)          {return fParent.appendChild (newChild); };
  381.            DOMNamedNodeMap* DOMDocumentTypeImpl::getAttributes() const                   {return fNode.getAttributes (); };
  382.            DOMNodeList*     DOMDocumentTypeImpl::getChildNodes() const                   {return fParent.getChildNodes (); };
  383.            DOMNode*         DOMDocumentTypeImpl::getFirstChild() const                   {return fParent.getFirstChild (); };
  384.            DOMNode*         DOMDocumentTypeImpl::getLastChild() const                    {return fParent.getLastChild (); };
  385.      const XMLCh*           DOMDocumentTypeImpl::getLocalName() const                    {return fNode.getLocalName (); };
  386.      const XMLCh*           DOMDocumentTypeImpl::getNamespaceURI() const                 {return fNode.getNamespaceURI (); };
  387.            DOMNode*         DOMDocumentTypeImpl::getNextSibling() const                  {return fChild.getNextSibling (); };
  388.      const XMLCh*           DOMDocumentTypeImpl::getNodeValue() const                    {return fNode.getNodeValue (); };
  389.            DOMDocument*     DOMDocumentTypeImpl::getOwnerDocument() const                {return fParent.fOwnerDocument; };
  390.      const XMLCh*           DOMDocumentTypeImpl::getPrefix() const                       {return fNode.getPrefix (); };
  391.            DOMNode*         DOMDocumentTypeImpl::getParentNode() const                   {return fChild.getParentNode (this); };
  392.            DOMNode*         DOMDocumentTypeImpl::getPreviousSibling() const              {return fChild.getPreviousSibling (this); };
  393.            bool             DOMDocumentTypeImpl::hasChildNodes() const                   {return fParent.hasChildNodes (); };
  394.            DOMNode*         DOMDocumentTypeImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
  395.                                                                                          {return fParent.insertBefore (newChild, refChild); };
  396.            void             DOMDocumentTypeImpl::normalize()                             {fParent.normalize (); };
  397.            DOMNode*         DOMDocumentTypeImpl::removeChild(DOMNode *oldChild)          {return fParent.removeChild (oldChild); };
  398.            DOMNode*         DOMDocumentTypeImpl::replaceChild(DOMNode *newChild, DOMNode *oldChild)
  399.                                                                                          {return fParent.replaceChild (newChild, oldChild); };
  400.            bool             DOMDocumentTypeImpl::isSupported(const XMLCh *feature, const XMLCh *version) const
  401.                                                                                          {return fNode.isSupported (feature, version); };
  402.            void             DOMDocumentTypeImpl::setPrefix(const XMLCh  *prefix)         {fNode.setPrefix(prefix); };
  403.            bool             DOMDocumentTypeImpl::hasAttributes() const                   {return fNode.hasAttributes(); };
  404.            bool             DOMDocumentTypeImpl::isSameNode(const DOMNode* other) const  {return fNode.isSameNode(other); };
  405.            void*            DOMDocumentTypeImpl::setUserData(const XMLCh* key, void* data, DOMUserDataHandler* handler)
  406.                                                                                          {return fNode.setUserData(key, data, handler); };
  407.            void*            DOMDocumentTypeImpl::getUserData(const XMLCh* key) const     {return fNode.getUserData(key); };
  408.            const XMLCh*     DOMDocumentTypeImpl::getBaseURI() const                      {return fNode.getBaseURI(); };
  409.            short            DOMDocumentTypeImpl::compareTreePosition(const DOMNode* other) const {return fNode.compareTreePosition(other); };
  410.            const XMLCh*     DOMDocumentTypeImpl::getTextContent() const                  {return fNode.getTextContent(); };
  411.            void             DOMDocumentTypeImpl::setTextContent(const XMLCh* textContent){fNode.setTextContent(textContent); };
  412.            const XMLCh*     DOMDocumentTypeImpl::lookupNamespacePrefix(const XMLCh* namespaceURI, bool useDefault) const  {return fNode.lookupNamespacePrefix(namespaceURI, useDefault); };
  413.            bool             DOMDocumentTypeImpl::isDefaultNamespace(const XMLCh* namespaceURI) const {return fNode.isDefaultNamespace(namespaceURI); };
  414.            const XMLCh*     DOMDocumentTypeImpl::lookupNamespaceURI(const XMLCh* prefix) const  {return fNode.lookupNamespaceURI(prefix); };
  415.            DOMNode*         DOMDocumentTypeImpl::getInterface(const XMLCh* feature)      {return fNode.getInterface(feature); };
  416. bool DOMDocumentTypeImpl::isEqualNode(const DOMNode* arg) const
  417. {
  418.     if (isSameNode(arg)) {
  419.         return true;
  420.     }
  421.     if (!fNode.isEqualNode(arg)) {
  422.         return false;
  423.     }
  424.     DOMDocumentType* argDT = (DOMDocumentType*) arg;
  425.     // check the string values
  426.     if (!getPublicId()) {
  427.         if (argDT->getPublicId()) {
  428.             return false;
  429.         }
  430.     }
  431.     else if (!XMLString::equals(getPublicId(), argDT->getPublicId())) {
  432.         return false;
  433.     }
  434.     if (!getSystemId()) {
  435.         if (argDT->getSystemId()) {
  436.             return false;
  437.         }
  438.     }
  439.     else if (!XMLString::equals(getSystemId(), argDT->getSystemId())) {
  440.         return false;
  441.     }
  442.     if (!getInternalSubset()) {
  443.         if (argDT->getInternalSubset()) {
  444.             return false;
  445.         }
  446.     }
  447.     else if (!XMLString::equals(getInternalSubset(), argDT->getInternalSubset())) {
  448.         return false;
  449.     }
  450.     // check the notations
  451.     if (getNotations()) {
  452.         if (!argDT->getNotations())
  453.             return false;
  454.         DOMNamedNodeMap* map1 = getNotations();
  455.         DOMNamedNodeMap* map2 = argDT->getNotations();
  456.         XMLSize_t len = map1->getLength();
  457.         if (len != map2->getLength()) {
  458.             return false;
  459.         }
  460.         for (XMLSize_t i = 0; i < len; i++) {
  461.             DOMNode* n1 = map1->item(i);
  462.             DOMNode* n2 = map2->getNamedItem(n1->getNodeName());
  463.             if (!n2 || !n1->isEqualNode(n2)) {
  464.                 return false;
  465.             }
  466.         }
  467.     }
  468.     else {
  469.         if (argDT->getNotations())
  470.             return false;
  471.     }
  472.     // check the entities
  473.     if (getEntities()) {
  474.         if (!argDT->getEntities())
  475.             return false;
  476.         DOMNamedNodeMap* map1 = getEntities();
  477.         DOMNamedNodeMap* map2 = argDT->getEntities();
  478.         XMLSize_t len = map1->getLength();
  479.         if (len != map2->getLength()) {
  480.             return false;
  481.         }
  482.         for (XMLSize_t i = 0; i < len; i++) {
  483.             DOMNode* n1 = map1->item(i);
  484.             DOMNode* n2 = map2->getNamedItem(n1->getNodeName());
  485.             if (!n2 || !n1->isEqualNode(n2)) {
  486.                 return false;
  487.             }
  488.         }
  489.     }
  490.     else {
  491.         if (argDT->getEntities())
  492.             return false;
  493.     }
  494.     return fParent.isEqualNode(arg);
  495. };
  496. XERCES_CPP_NAMESPACE_END