Here are some patches for implementing:
        DOM_Element DOM_Document::getElementById(DOMString)

Like I said the other day, I really needed this function so I decided to
implement it myself.  The patches are off of the beta code that was released
on Friday, so it shouldn't be far off.  I used Xerces-J as my example in
implementing this, but if someone who knows the architecture of Xerces a
little better than I could look these over, and let me know if there is
anything that I have missed I would appreciate it...

Thanks


--- documentimpl.cpp    Thu Feb 10 19:43:32 2000
+++ g:documentimpl.cpp  Mon Feb 14 08:50:30 2000
@@ -55,7 +55,10 @@
  */
 
 /**
- * $Log: DocumentImpl.cpp,v $
+ * $Log: documentimpl.cpp,v $
+ * Revision 1.3  2000-02-14 08:50:30-07  jdl
+ * Implemented getElementById()
+ *
  * Revision 1.10  2000/02/10 23:35:11  andyh
  * Update DOM_DOMImplementation::CreateDocumentType and
  * DOM_DocumentType to match latest from W3C
@@ -130,6 +133,31 @@
 
 static DOMString *nam = 0;  // Will be lazily initialized to "#document"
 
+
+// ---------------------------------------------------------------------------
+//  StringPool::PoolElem: Constructors and Destructor
+// ---------------------------------------------------------------------------
+DocumentImpl::PoolElem::PoolElem( const DOMString string
+                                  , const DOM_Element &elem) :
+    fElem((DOM_Element&)elem)
+    , fString(string)
+{
+}
+
+DocumentImpl::PoolElem::~PoolElem()
+{
+}
+
+// ---------------------------------------------------------------------------
+//  DocumentImpl::PoolElem: Public methods
+// ---------------------------------------------------------------------------
+const XMLCh* DocumentImpl::PoolElem::getKey() const
+{
+    return fString.rawBuffer();
+}
+
+
+
 DocumentImpl::DocumentImpl(): NodeImpl(null,
                                        
DStringPool::getStaticString("#document", &nam),
                                        DOM_Node::DOCUMENT_NODE,
@@ -139,6 +167,7 @@
     docType=null;
     docElement=null;
     namePool = new DStringPool(257);
+    identifiers = new RefHashTableOf<PoolElem>(109);
     iterators = 0L;
     treeWalkers = 0L;
 };
@@ -619,9 +648,21 @@
 
 ElementImpl *DocumentImpl::getElementById(const DOMString &elementId)
 {
-    return null;    //not implemented yet
+       PoolElem *elem = identifiers->get(elementId.rawBuffer());
+       if (elem)
+       {
+               return (ElementImpl*)elem->fElem.fImpl;
+       }
+
+       return null;
 }
 
+// Non-standard accessory functions */
+
+void DocumentImpl::putIdentifier(const DOMString &elementId, const DOM_Element 
&ele)
+{
+       identifiers->put(new PoolElem(elementId, ele));
+}
 
 //Return the index > 0 of ':' in the given qualified name 
qName="prefix:localName".
 //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
--- documentimpl.hpp    Thu Feb 10 19:43:32 2000
+++ g:documentimpl.hpp  Mon Feb 14 08:50:30 2000
@@ -58,7 +58,10 @@
  */
 
 /**
- * $Log: DocumentImpl.hpp,v $
+ * $Log: documentimpl.hpp,v $
+ * Revision 1.3  2000-02-14 08:50:30-07  jdl
+ * Implemented getElementById()
+ *
  * Revision 1.6  2000/02/10 23:35:11  andyh
  * Update DOM_DOMImplementation::CreateDocumentType and
  * DOM_DocumentType to match latest from W3C
@@ -99,7 +102,9 @@
 #include <util/XML4CDefs.hpp>
 #include "NodeImpl.hpp"
 #include "DOM_Node.hpp"
+#include "DOM_Element.hpp"
 #include "util/RefVectorOf.hpp"
+#include "util/RefHashTableOf.hpp"
 
 class DocumentTypeImpl;
 class ElementImpl;
@@ -120,24 +125,40 @@
 class DOM_NodeFilter;
 class NodeFilterImpl;
 class DOM_DOMImplementation;
-
+class DOMString;
 
 typedef RefVectorOf<NodeIteratorImpl> NodeIterators;
 typedef RefVectorOf<TreeWalkerImpl> TreeWalkers;
 
 
-
 class CDOM_EXPORT DocumentImpl: public NodeImpl {
 private:
+private:
+    // -----------------------------------------------------------------------
+    //  Private data types
+    // -----------------------------------------------------------------------
+    class PoolElem
+    {
+        public :
+            PoolElem(const DOMString string, const DOM_Element &elem);
+            ~PoolElem();
+
+            const XMLCh* getKey() const;
+
+            DOM_Element                 fElem;
+            DOMString        fString;
+    };
+
     DocumentTypeImpl            *docType;
     ElementImpl                 *docElement;
     DStringPool                 *namePool;
-    NodeIterators                 *iterators;
-    TreeWalkers                   *treeWalkers;
+
+    RefHashTableOf<PoolElem>   *identifiers;
+    NodeIterators               *iterators;
+    TreeWalkers                 *treeWalkers;
     friend class NodeIteratorImpl;
     friend class TreeWalkerImpl;
 
-
 public:
     DocumentImpl();
     DocumentImpl(const DOMString &namespaceURI,            //DOM Level 2
@@ -179,6 +200,10 @@
     virtual DeepNodeListImpl    *getElementsByTagNameNS(const DOMString 
&namespaceURI,
        const DOMString &localName);
     virtual ElementImpl         *getElementById(const DOMString &elementId);
+
+       // Non-standard accessory functions
+    virtual void                        putIdentifier(const DOMString 
&elementId, const DOM_Element &ele);
+
     //Return the index > 0 of ':' in the given qualified name 
qName="prefix:localName".
     //Return 0 if there is no ':', or -1 if qName is malformed such as ":abcd".
     static  int                 indexofQualifiedName(const DOMString & qName);
--- dom_document.cpp    Thu Feb 10 19:43:34 2000
+++ g:dom_document.cpp  Mon Feb 14 08:51:00 2000
@@ -55,7 +55,10 @@
  */
 
 /**
- * $Log: DOM_Document.cpp,v $
+ * $Log: dom_document.cpp,v $
+ * Revision 1.3  2000-02-14 08:51:00-07  jdl
+ * Implemented getElementById()
+ *
  * Revision 1.5  2000/02/06 07:47:28  rahulj
  * Year 2K copyright swat.
  *
@@ -257,4 +260,12 @@
 DOM_Element         DOM_Document::getElementById(const DOMString &elementId)
 {
         return DOM_Element(((DocumentImpl *)fImpl)->getElementById(elementId));
+}
+
+
+// Non-standard accessory functions */
+
+void DOM_Document::putIdentifier(const DOMString &elementId, const DOM_Element 
&ele)
+{
+       ((DocumentImpl*)fImpl)->putIdentifier(elementId,ele);
 }
--- dom_document.hpp    Thu Feb 10 19:43:34 2000
+++ g:dom_document.hpp  Mon Feb 14 08:51:00 2000
@@ -55,7 +55,10 @@
  */
 
 /**
- * $Log: DOM_Document.hpp,v $
+ * $Log: dom_document.hpp,v $
+ * Revision 1.3  2000-02-14 08:51:00-07  jdl
+ * Implemented getElementById()
+ *
  * Revision 1.7  2000/02/10 19:41:16  abagchi
  * Added docs for createNodeIterator and createTreeWalker
  *
@@ -382,7 +385,6 @@
                                         unsigned long whatToShow, 
                                         DOM_NodeFilter*  filter, 
                                         bool entityReferenceExpansion);
-
      /**
      * Creates a TreeWalker object.   (DOM2)
      *
@@ -576,6 +578,21 @@
 
     //@}
 
+    /** @name Non-standard accessory functions */
+    //@{
+
+       /**
+        * Registers an identifier name with a specified element node.
+        * If the identifier is already registered, the new element
+        * node replaces the previous node. If the specified element
+        * node is null, removeIdentifier() is called.
+        *
+     * @param elementId The unique <code>id</code> value for an element.
+     * @param ele The <code>Element</code> unique <code>id</code> value for an 
element.
+     */
+    void                        putIdentifier(const DOMString &elementId, 
const DOM_Element &ele);
+
+       //@}
 protected:
     DOM_Document (DocumentImpl *impl);
 
--- domparser.cpp       Thu Feb 10 19:43:48 2000
+++ g:domparser.cpp     Mon Feb 14 08:51:28 2000
@@ -59,7 +59,10 @@
 *  handler with the scanner. In these handler methods, appropriate DOM nodes
 *  are created and added to the DOM tree.
 *
-* $Log: DOMParser.cpp,v $
+* $Log: domparser.cpp,v $
+* Revision 1.3  2000-02-14 08:51:28-07  jdl
+* Implemented getElementById()
+*
 * Revision 1.7  2000/02/06 07:47:56  rahulj
 * Year 2K copyright swat.
 *
@@ -130,8 +133,8 @@
     
     fNodeStack = new ValueStackOf<DOM_Node>(64);
     this->reset();
-    
-    
+
+ 
 }
 
 
@@ -225,7 +228,7 @@
         fScanner->scanDocument(source, reuseValidator);
         fParseInProgress = false;
     }
-    
+
     catch(...)
     {
         fParseInProgress = false;
@@ -372,7 +375,6 @@
 }
 
 
-
 // ---------------------------------------------------------------------------
 //  DOMParser: Implementation of XMLEntityHandler interface
 // ---------------------------------------------------------------------------
@@ -540,12 +542,25 @@
             }
             elem.setAttributeNS(namespaceURI, oneAttrib -> getQName(),
                 oneAttrib -> getValue());
+
+                       // Register identifiers
+                       if (oneAttrib->getType()==XMLAttDef::ID)
+                       {
+                               fDocument.putIdentifier(oneAttrib->getValue(), 
elem);
+                       }
         }
     } else {   //DOM Level 1
+
         elem = fDocument.createElement(elemDecl.getFullName());
         for (unsigned int index = 0; index < attrCount; ++index) {
             const XMLAttr* oneAttrib = attrList.elementAt(index);
             elem.setAttribute(oneAttrib->getName(), oneAttrib->getValue());
+
+                       // Register identifiers
+                       if (oneAttrib->getType()==XMLAttDef::ID)
+                       {
+                               fDocument.putIdentifier(oneAttrib->getValue(), 
elem);
+                       }
         }
     }
     

Reply via email to