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]