> 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]

Reply via email to