I agree with you that the runtime warning from the code about calling a pure 
virtual function is indeed very odd because of how C++ should work and 
because other code which uses the other XObjectFactory methods (such as 
createNumber) do not trigger that warning yet are also pure virtuals in the 
super class.

I also realized last night that it doesn't suffice to copy the node references 
into the mutable node reference list for the DOM document because the target 
Document node (and its children) are not yet owned by something of greater 
scope than the immediate stack frame. I was seeking a createDocument method 
of either the executionContext or the executionContext's XObjectFactory.

Although I never would have guessed the solution you propose, having it before 
me I can see how and why it might succeed.

I do believe that in step 3 below, I will need to change the call to "myProxy" 
to "myNodeSet"...

Thank you for your prompt reply (and for an impressive collection of code in 
Xalan-C++).

On Tuesday 24 May 2005 11:41 pm, [EMAIL PROTECTED] wrote:
> > While attempting to see if this "just works", I find that the call to
> > executionContext.getXObjectFactory().createNodeSet( theNodeList )
>
> results in
>
> > a runtime error because the getXObjectFactory method returns a reference
>
> to
>
> > the XObjectFactory "interface" (ie the superclass) and therein
>
> createNodeSet
>
> > is a pure virtual (ie abstract) method.
>
> That seems strange, because the same code is used in many places in
> Xalan-C.
>
> > In order for the appropriate XObjectFactory createNodeSet() method to
>
> get
>
> > called, the reference returned from the getXObjectFactory() method has
>
> to be
>
> > cast to the derived XObjectFactoryDefault class which has the
>
> implemented
>
> > version of createNodeSet...
>
> Again, I find that hard to believe.  Regardless of how you cast the
> reference, the underlying object is the same.
>
> The main reason your approach won't work is because you are adding a
> reference to a stack-based object to the MutableNodeRefList instance:
>
>  theNodeList->addNode( xercesDocWrapper );
>
> That is certain to cause undefined behavior, since the object is destroyed
> when the block exits.
>
> What you want to do is not difficult to implement.  The main thing you
> need is an object to own the Xerces-C DOMDocument instance you create,
> along with the "node set" you want to return.  If you always return a
> node-set containing a single Document node, then you should do the
> following:
>
> 1. Create a class that derives from XNodeSetBase:
>
> #include "xercesc/dom/DOMDocument.hpp"
>
> #include "xalanc/XPath/XNodeSetBase.hpp"
> #include "xalanc/XPath/XNodeSetNodeProxy.hpp"
> #include "xalanc/XercesParserLiaison/XercesDocumentWrapper.hpp"
>
> XALAN_USING_XERCES(MemoryManager)
> XALAN_USING_XERCES(DOMDocument)
> XALAN_USING_XALAN(XNodeSetBase)
> XALAN_USING_XALAN(XNodeSetNodeProxy)
> XALAN_USING_XALAN(NodeRefListBase)
> XALAN_USING_XALAN(XalanNode)
> XALAN_USING_XALAN(XercesDocumentWrapper)
>
> class myNodeSet : public XNodeSetBase
> {
> public:
>
>     myNodeSet(
>         MemoryManager&  manager,
>         DOMDocument*    document) :
>         XNodeSetBase(manager),
>         m_wrapper(
>             manager,
>             document,
>             true,
>             true),
>         m_proxy(&m_wrapper)
>     {
>     }
>
>     virtual
>     ~myNodeSet()
>     {
>         delete m_wrapper.getXercesDocument();
>     }
>
>     virtual void
>     dereferenced()
>     {
>         delete this;
>     }
>
>     virtual const NodeRefListBase&
>     nodeset() const
>     {
>         return m_proxy.nodeset();
>     }
>
>     virtual XalanNode*
>     item(size_type      index) const
>     {
>         return m_proxy.item(index);
>     }
>
>     virtual size_type
>     getLength() const
>     {
>         return m_proxy.getLength();
>     }
>
> private:
>
>     XercesDocumentWrapper    m_wrapper;
>
>     // This is an existing Xalan-C class
>     // that "adapts" a single node, making it
>     // look like a node set with a single node.
>     const XNodeSetNodeProxy  m_proxy;
> };
>
> 2. In your extension function, do everything you need to create the
> Xerces-C DOMDocument instance.
>
> 3. Create a new instance of the class and wrap it in an XObjectPtr
> instance:
>
>     XObject* const   theObject = new myProxy
> (executionContext.getMemoryManager(), queryResultDom);
>
>     return XObjectPtr(*theObject);
>
> Note this is not necessarily compiled and tested, but it will give you an
> idea of what you need to do.
>
> Dave
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]

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

Reply via email to