Title: XPathWrapper Question

Hi All,

We have a wrapper over the Xerces Library that also supports Xpath using Xalan.  The Xpath support code that we have is taken from XPathWrapper sample code available in the Xalan samples.  We have ran into issue with using Xpath with nested namespaces.   The problem occurs if you have nested namespace declarations and can be reproduced using the XPathWrapper Sample.

A sample XML file which causes the problem:

<rootns:root xmlns:rootns="http://root.com/rootnode/">
        <q1:foo xmlns:q1="http://q1.org/message/"/>
</rootns:root>

To reproduce the issue: Invoke XPathWrapper with the following option

C:\>XPathWrapper c:\xpathtest.xml / /rootns:root:/q1:foo

The sample works if the namespace declaration for q1 is moved to the root node.  However, we cannot change the declaration.  The issue  occurs in the execute statement in the code. 

For sake of completeness, here is snippet of sample code that I used to convert from Xerces to Xalan DOM and call Xpath to reproduce the problem.  Like I mentioned earlier, the problem can be reproduced using the XpathWrapper sample also.   I can post the whole source code if anyone is interested.  The error I get in my sample is

Prefix must resolve to a namespace: q1.
_expression_ = '/rootns:root/q1:foo' Remaining tokens are:  ('/' 'rootns' ':' 'root' '/')

Is this the right way to call Xpath queries on Xerces DOM objects?  What do I need to change to fix the issue? Any suggestions will be greatly appreciated.

Thanks,

Ravin

///////////From mySample.cpp////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
DOMNode *gDOMNode;

//Node is populated using MemBufInputSource()


DOMDocument* xercesDocument = NULL;
if( gDOMNode->getNodeType() != 9 /*DOCUMENT_NODE*/ )
{
    xercesDocument = gDOMNode->getOwnerDocument();
}
else
{
    xercesDocument = (DOMDocument*)gDOMNode;
}

if( NULL == xercesDocument )
{
    wcout <<  L"Document node is NULL." << endl;
}
               
XercesDOMSupport theDOMSupport;
XercesDocumentWrapper theWrapper(xercesDocument, false, false);

// Initialize the XPath subsystem
static XPathInit theInit;

// configure the objects needed for XPath to work with the Xerces DOM
XPathEnvSupportDefault                  theEnvSupport;
XObjectFactoryDefault                   theXObjectFactory;
XPathExecutionContextDefault    theExecutionContext(theEnvSupport, theDOMSupport, theXObjectFactory);
XPathFactoryDefault                             theXPathFactory;
XPathProcessorImpl                              theXPathProcessor;
               
XalanElement*   rootElem = theWrapper.getDocumentElement();
XalanNode*      currentNode = theWrapper.mapNode(gDOMNode);
               
// first get the context nodeset
XPath* const contextXPath = theXPathFactory.create(); //will be deleted by theXPathFactory destructor
XPathConstructionContextDefault         theXPathConstructionContext;


theXPathProcessor.initXPath(*contextXPath,
            theXPathConstructionContext,
                        XalanDOMString(strQuery.c_str()),
                        ElementPrefixResolverProxy(rootElem, theEnvSupport, theDOMSupport));
               
XObjectPtr      xObj = contextXPath->execute(currentNode,
                        ElementPrefixResolverProxy(rootElem, theEnvSupport, theDOMSupport),
                        theExecutionContext);

Reply via email to