John Snelson wrote:
Boris Kolpackov wrote:
Having given it some thought, I think that merging the two would be the
best idea - it would be a breaking change for XQilla users, but it would
be a move to a more standard API.

Agree. If you can come up with a patch, I will review and commit it.

I've attached a patch against the SVN trunk for the XPath API changes we've discussed.

I think I sent that out a bit quick. This new patch implements the new API in the existing implementation objects, so that Xerces-C will compile with the patch applied.

I've also changed my mind (again) about the DOMXPathResult object. The problem is this - DOMXPathResult::iterateNext() returns DOMNode, because in XPath 1 you can only get single values of a list of nodes. XQilla's XPath2Result::iterateNext() returns a bool, and simply moved the iterator to look at the next item in the sequence, which in XPath 2.0 can be a heterogeneous sequence of nodes and values. The same is true for snapshotItem(). I've come to the conclusion that it would be best for XQilla to stick with the XPath2Result API, and it would be good if Xerces-C incorporated it into it's API.

Any questions or opinions?

John

--
John Snelson, Oracle Corporation            http://snelson.org.uk/john
Berkeley DB XML:            http://oracle.com/database/berkeley-db/xml
XQilla:                                  http://xqilla.sourceforge.net
Index: src/xercesc/dom/DOMXPathNSResolver.hpp
===================================================================
--- src/xercesc/dom/DOMXPathNSResolver.hpp      (revision 652795)
+++ src/xercesc/dom/DOMXPathNSResolver.hpp      (working copy)
@@ -95,14 +95,29 @@
      *
      * XPath2 implementations require a reverse lookup in the static context.
      * Look up the prefix associated with the namespace URI
-     * The XPath evaluator must never call this with a null or empty argument, 
-     * because the result of doing this is undefined.
      * @param URI of type XMLCh - The namespace to look for.
      * @return the associated prefix or null if none is found.
      */
     virtual const XMLCh*          lookupPrefix(const XMLCh* URI) const = 0;
 
+    /**
+     * Non-standard extension
+     *
+     * Associate the given namespace prefix to the namespace URI.
+     * @param prefix of type XMLCh - The namespace prefix to bind.
+     * @param URI of type XMLCh - The associated namespace URI.
+     */
+    virtual void addNamespaceBinding(const XMLCh* prefix, const XMLCh* uri) = 
0;
 
+    /**
+     * Called to indicate that this object (and its associated children) is no 
longer in use
+     * and that the implementation may relinquish any resources associated 
with it and
+     * its associated children.
+     *
+     * Access to a released object will lead to unexpected result.
+     */
+    virtual void release() = 0;
+
     //@}
 };
 
Index: src/xercesc/dom/impl/DOMDocumentImpl.cpp
===================================================================
--- src/xercesc/dom/impl/DOMDocumentImpl.cpp    (revision 652795)
+++ src/xercesc/dom/impl/DOMDocumentImpl.cpp    (working copy)
@@ -427,9 +427,9 @@
     return new (getMemoryManager()) DOMXPathExpressionImpl(expression, 
resolver, getMemoryManager());
 }
 
-const DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(const DOMNode 
*nodeResolver)
+DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(const DOMNode 
*nodeResolver)
 {
-    return new (this) DOMXPathNSResolverImpl(nodeResolver);
+    return new (getMemoryManager()) DOMXPathNSResolverImpl(nodeResolver, 
getMemoryManager());
 }
 
 void* DOMDocumentImpl::evaluate(const XMLCh *expression, const DOMNode 
*contextNode, const DOMXPathNSResolver *resolver, 
Index: src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp
===================================================================
--- src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp     (revision 652795)
+++ src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp     (working copy)
@@ -23,22 +23,31 @@
 #define XERCESC_INCLUDE_GUARD_DOMXPATHNSRESOLVERIMPL_HPP
 
 #include <xercesc/util/XercesDefs.hpp>
+#include <xercesc/util/XMemory.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
 #include <xercesc/dom/DOMXPathNSResolver.hpp>
+#include <xercesc/util/KVStringPair.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
 class DOMNode;
 
-class CDOM_EXPORT DOMXPathNSResolverImpl : public DOMXPathNSResolver
+class CDOM_EXPORT DOMXPathNSResolverImpl : public XMemory,
+                                           public DOMXPathNSResolver
 {
 public:
-    DOMXPathNSResolverImpl(const DOMNode *nodeResolver);
+    DOMXPathNSResolverImpl(const DOMNode* nodeResolver = 0, MemoryManager* 
const manager = XMLPlatformUtils::fgMemoryManager);
 
     virtual const XMLCh*          lookupNamespaceURI(const XMLCh* prefix) 
const;
     virtual const XMLCh*          lookupPrefix(const XMLCh* URI) const;
+    virtual void                  addNamespaceBinding(const XMLCh* prefix, 
const XMLCh* uri);
 
+    virtual void                  release();
+
 protected:
+    RefHashTableOf<KVStringPair>  fNamespaceBindings;
     const DOMNode*                fResolverNode;
+    MemoryManager*                fManager;
 };
 
 XERCES_CPP_NAMESPACE_END
Index: src/xercesc/dom/impl/DOMDocumentImpl.hpp
===================================================================
--- src/xercesc/dom/impl/DOMDocumentImpl.hpp    (revision 652795)
+++ src/xercesc/dom/impl/DOMDocumentImpl.hpp    (working copy)
@@ -142,7 +142,7 @@
     virtual void                 removeNodeIterator(DOMNodeIteratorImpl* 
nodeIterator); //non-standard api
 
     virtual const DOMXPathExpression*    createExpression(const XMLCh 
*expression, const DOMXPathNSResolver *resolver);
-    virtual const DOMXPathNSResolver*    createNSResolver(const DOMNode 
*nodeResolver);
+    virtual DOMXPathNSResolver*    createNSResolver(const DOMNode 
*nodeResolver);
     virtual void* evaluate(const XMLCh *expression, const DOMNode 
*contextNode, const DOMXPathNSResolver *resolver, 
                            unsigned short type, void* result);
 
Index: src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp
===================================================================
--- src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp     (revision 652795)
+++ src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp     (working copy)
@@ -18,30 +18,68 @@
 #include "DOMXPathNSResolverImpl.hpp"
 #include <xercesc/dom/DOMNode.hpp>
 #include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/Janitor.hpp>
+#include <xercesc/util/XMLString.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
-DOMXPathNSResolverImpl::DOMXPathNSResolverImpl(const DOMNode *nodeResolver):
- fResolverNode(nodeResolver)
+DOMXPathNSResolverImpl::DOMXPathNSResolverImpl(const DOMNode *nodeResolver, 
MemoryManager* const manager) :
+    fNamespaceBindings(7, true, manager),
+    fResolverNode(nodeResolver),
+    fManager(manager)
 {
 }
 
 const XMLCh* DOMXPathNSResolverImpl::lookupNamespaceURI(const XMLCh* prefix) 
const
 {
-    if (XMLString::equals(prefix, XMLUni::fgXMLString))
+    if(XMLString::equals(prefix, XMLUni::fgXMLString))
         return XMLUni::fgXMLURIName;
+
+    const KVStringPair *pair = fNamespaceBindings.get((void*)prefix);
+    if(pair) {
+        if(*pair->getValue() == 0) return NULL;
+        return pair->getValue();
+    }
+
     if(fResolverNode)
         return fResolverNode->lookupNamespaceURI(prefix);
+
     return NULL;
 }
 
-const XMLCh* DOMXPathNSResolverImpl::lookupPrefix(const XMLCh* URI) const
+const XMLCh* DOMXPathNSResolverImpl::lookupPrefix(const XMLCh* uri) const
 {
-    if (XMLString::equals(URI, XMLUni::fgXMLURIName))
+    if(XMLString::equals(uri, XMLUni::fgXMLURIName))
         return XMLUni::fgXMLString;
+
+    RefHashTableOfEnumerator<KVStringPair> 
enumerator((RefHashTableOf<KVStringPair>*)&fNamespaceBindings);
+    while(enumerator.hasMoreElements()) {
+        KVStringPair &pair = enumerator.nextElement();
+        if(XMLString::equals(pair.getValue(), uri)) {
+            return pair.getKey();
+        }
+    }
+
     if(fResolverNode)
-        return fResolverNode->lookupPrefix(URI);
+        return fResolverNode->lookupPrefix(uri);
+
     return NULL;
 }
 
+void DOMXPathNSResolverImpl::addNamespaceBinding(const XMLCh* prefix, const 
XMLCh* uri)
+{
+    if(prefix == 0) prefix = XMLUni::fgZeroLenString;
+    if(uri == 0) uri = XMLUni::fgZeroLenString;
+
+    KVStringPair* pair = new (fManager) KVStringPair(prefix, uri, fManager);
+
+    fNamespaceBindings.put((void*)pair->getKey(), pair);
+}
+
+void DOMXPathNSResolverImpl::release()
+{
+    DOMXPathNSResolverImpl* me=(DOMXPathNSResolverImpl*)this;
+    delete me;
+}
+
 XERCES_CPP_NAMESPACE_END
Index: src/xercesc/dom/DOMXPathEvaluator.hpp
===================================================================
--- src/xercesc/dom/DOMXPathEvaluator.hpp       (revision 652795)
+++ src/xercesc/dom/DOMXPathEvaluator.hpp       (working copy)
@@ -114,11 +114,13 @@
      * information available in the node's hierarchy at the time 
lookupNamespaceURI 
      * is called. also correctly resolving the implicit xml prefix.
      * @param nodeResolver of type <code>DOMNode</code> The node to be used as 
a context 
-     * for namespace resolution.
+     * for namespace resolution. If this parameter is null, an unpopulated
+     * <code>DOMXPathNSResolver</code> is returned, which can be populated 
using the
+     * Xerces-C extension 
<code>DOMXPathNSResolver::addNamespaceBinding()</code>.
      * @return <code>DOMXPathNSResolver</code> The object which resolves 
namespaces 
      * with respect to the definitions in scope for the specified node.
      */
-    virtual const DOMXPathNSResolver*    createNSResolver(const DOMNode 
*nodeResolver) = 0;
+    virtual DOMXPathNSResolver*    createNSResolver(const DOMNode 
*nodeResolver) = 0;
 
 
     /**

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to