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