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