Hi Dave,

I want to achieve the following:

I have a XercesDOM document object. There is an XPath expression like the 
following, for
, say, one attribute's value: cube(id('id1')). Here, id() is the XPath 
function, id1 is the id of an element
whose value is, say, 10. Cube is a function that I want to implement. I have to 
get the result 1000
when this XPath expression is evaluated. 

Please note that I should not have to have any XSL file. Everything has to be 
done in-memory.
Also, I need not do any transform on the input document. Only what I need to do 
is get the XPath
expression evaluated to get the correct value.

I have the following code. It returns correct value for id('id1'), but for 
cube(id('id1')) it throws 
xalanc::XPathParserException exception.

I will be grateful if you could please let me know where I am doing stuffs
wrong, and how to do it correctly to get the desired output.

Code:

XALAN_USING_XERCES(XMLPlatformUtils)
                XALAN_USING_XERCES(XMLException)
        XALAN_USING_XALAN(Function)
        XALAN_USING_XALAN(XalanTransformer)
     XALAN_USING_XALAN(XalanDOMString)
     XALAN_USING_XALAN(XalanDocument)
     XALAN_USING_XALAN(XalanElement)
     XALAN_USING_XALAN(XalanNode)
     XALAN_USING_XALAN(XercesDOMSupport)
     XALAN_USING_XALAN(XercesParserLiaison)
     XALAN_USING_XALAN(XPathEvaluator)
     XALAN_USING_XALAN(ElementPrefixResolverProxy)
     XALAN_USING_XALAN(XercesDocumentWrapper)
         XALAN_USING_XALAN(XObjectPtr)
         XALAN_USING_XALAN(XPathExecutionContext)
         XALAN_USING_XALAN(MemoryManagerType)
         XALAN_USING_XALAN(XalanCopyConstruct)

class FunctionCube : public Function
{
public:

        
        virtual XObjectPtr
        execute(
                        XPathExecutionContext&                  
executionContext,
                        XalanNode*                                              
context,
                        const XObjectArgVectorType&             args,
                        const LocatorType*                              
locator) const
        {
                if (args.size() != 1)
                {
            XPathExecutionContext::GetAndReleaseCachedString    
theGuard(executionContext);

                        executionContext.error(getError(theGuard.get()), 
context, locator);
                }

                assert(args[0].null() == false);        

#if defined(XALAN_STRICT_ANSI_HEADERS)
                using std::pow;
#endif

                return 
executionContext.getXObjectFactory().createNumber(pow(args[0]->num(), 3));
        }

#if !defined(XALAN_NO_USING_DECLARATION)
        using Function::execute;
#endif

        
#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
        virtual Function*
#else
        virtual FunctionCube*
#endif
        clone(MemoryManagerType&    theManager) const
        {
            return XalanCopyConstruct(theManager, *this);
        }

protected:

        
        const XalanDOMString&
        getError(XalanDOMString&    theResult) const
        {
        theResult.assign("The cube() function accepts one argument!");

                return theResult;
        }

private:

        // Not implemented...
        FunctionCube&
        operator=(const FunctionCube&);

        bool
        operator==(const FunctionCube&) const;
};

int foo(xercesc::DOMDocument *dom_document_, char* xpath, std::string& output)
{
        
         XMLPlatformUtils::Initialize();
         XalanTransformer::initialize();
         XPathEvaluator::initialize();

        
                        {
                                // Create a XalanTransformer.
                                XalanTransformer        theXalanTransformer;

                                const XalanDOMString    theNamespace(" ");

                                
                                theXalanTransformer.installExternalFunction(
                                        theNamespace,
                                        XalanDOMString("cube"),
                                        FunctionCube());

                                XercesDOMSupport      theDOMSupport;
                                XercesParserLiaison   
theParserLiaison(theDOMSupport);

                                XalanDocument*  theDocument =
                            theParserLiaison.createDocument(
                           dom_document_,
                                  true,
                              true,
                                  true);

                             XPathEvaluator  theEvaluator;

                             const XalanElement* const   theRootElement =
                             theDocument->getDocumentElement(); 

                             ElementPrefixResolverProxy 
thePrefixResolver(theRootElement);

                             XalanNode* const  theNode =
                                theEvaluator.selectSingleNode(
                                     theDOMSupport,
                                     theDocument,
                                        XalanDOMString("/").c_str(),
                                    thePrefixResolver);
                                 if(!theNode)
                                         return 1;

                                try
                                 {
                                         XalanDOMString str(xpath);
                                        const xalanc::XObjectPtr        
theResult(
                                        theEvaluator.evaluate(
                                                        theDOMSupport,
                                                        theNode,
                                                        
XalanDOMString(str).c_str()));
                        
                                        xalanc::XalanVector<char> charData1;
                                        string rtnStr1;
                                        theResult->str().transcode(charData1);
                                        rtnStr1.assign(charData1.begin(), 
charData1.end());
                                        output = rtnStr1; //put the result in 
output param
                                }
                                 catch(const xalanc::XPathParserException& e)
                                 {
                                         const xalanc::XalanDOMChar* ch = 
e.getType() ;
                                         char* ch1 = (char*)ch;
                                                 
                                 }

                
                        }

         XPathEvaluator::terminate();
         XalanTransformer::terminate();
       XMLPlatformUtils::Terminate();

        return 0;
}  


On Tue, 20 Feb 2007 David Bertoni wrote :
>Indrajit Bhattacharya wrote:
>>Dave,
>>
>>Yes. But I see it uses .xsl file as input to the transform() function. Is 
>>there any other way of doing it without using .xsl and any other file ?
>>
>>Thanks for your reply.
>>
>>-Indrajit
>>
>>
>>
>>
>>On Tue, 20 Feb 2007 David Bertoni wrote :
>>  >Indrajit Bhattacharya wrote:
>>  >>Hi,
>>  >>
>>  >>I have a query on XPath:
>>  >>
>>  >>Is it possible to add extra functions to XPath 1.0 specifications, such 
>> that Xalan could
>>  >>call those functions actually implemented by me in my application, 
>> without using XSL ?
>
>If you install the function as the sample shows, it will be available in the 
>XPathEvaluator from your XPath expressions.
>
>Dave

Reply via email to