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); + } } }